2010-06-30 7 views
11

लगभग हर बार जब मैं Graphics.DrawRectangle या Graphics.FillRectangle (int संस्करण) का उपयोग करता हूं) मुझे लगता है कि आयत की दाईं और निचली सीमा पर पिक्सेल याद आती है।FillRectangle और DrawRectangle के पिक्सेल व्यवहार

सटीक परिभाषा

Graphics.FillRectangle(brush,x,y,width,height) 

और

Graphics.DrawRectangle(pen,x,y,width,height) // pen is one pixel width, i.e. width=0f 

द्वारा भरा हो पिक्सल और इसके लिए एक तार्किक व्याख्या है जिनमें से क्या है? (तो मैं अंत में व्यवहार याद कर सकते हैं :) ...)

संपादित:

:

ओलेग ज़्हुक- के अद्भुत Try GDI+ आवेदन का उपयोग करना, मैं FillRectangle और DrawRectangle के बीच एक जिज्ञासु अंतर मिल पा रहा था FillRectangle(brush,0,0,1,1) एक बिंदु पर (0,0) खींचता है जो किसी भी तरह समझ में आता है (यह चौड़ाई और ऊंचाई के साथ एक आयताकार है)।

DrawRectangle(pen,0,0,1,1) दूसरी तरफ 2 से 2 पिक्सेल आयताकार खींचता है।

समान व्यवहार अन्य चौड़ाई/ऊंचाई संयोजन के लिए दिखाया गया है, DrawRectangle हमेशा बाईं और नीचे (जो एक छोटे से परेशान जैसे है जब ClientRectangle संपत्ति का उपयोग कर एक नियंत्रण के चारों ओर एक फ्रेम आकर्षित करने के लिए)

के लिए और अधिक एक पिक्सेल फैली

मेरा पहला प्रश्न हल किया गया (कैसे वे व्यवहार करते हैं ...) अभी भी दूसरा है: क्यों क्या वे इस तरह से व्यवहार करते हैं?

+0

मेरे हटाए गए उत्तर के बारे में खेद है - यह देर हो चुकी थी (मेरे शरीर की घड़ी से) और मैं ठीक से नहीं पढ़ रहा था, बस निष्कर्ष पर कूद रहा था। – Steve314

उत्तर

7

ये विधियां सही तरीके से काम करती हैं, आपको केवल एंटी-एलियासिंग और के खाते के प्रभावों को ध्यान में रखना होगा।

सबसे पहले, सब कुछ (न केवल गोल परिणाम) देखने के लिए विरोधी aliasing पर बारी:

graphics.SmoothingMode = SmoothingMode.AntiAlias; 

अब FillRectangle (10,10,10,10) धुँधली परिणाम और DrawRectangle का उत्पादन करेगा (10,10, 10,10) तेज होगा।

धुंधला परिणाम का मतलब है कि आपके पास पिक्सेल ऑफ-ग्रिड समन्वयित करता है।यदि आपको कॉल करने की आवश्यकता है:

graphics.FillRectangle(9.5f, 9.5f, 10, 10); 

ग्रिड पर आयताकार के ऊपरी-बाएं कोने को संरेखित करने के लिए।

DrawRectangle तेज है क्योंकि यह चौड़ाई 1.0 का उपयोग करता है। तो लाइन पिक्सेल केंद्र पर शुरू होती है और दोनों दिशाओं में 0.5 पिक्सल चलाती है, इस प्रकार बिल्कुल 1 पिक्सेल भरती है।

ध्यान दें कि चौड़ाई और ऊंचाई इस तरह से गणना: 19.5 एक सही/नीचे आयत भी ग्रिड पर गठबंधन की समन्वय है

width = (right - left) = 19.5 - 9.5 = 10 
height = (bottom - top) = ... 

सूचना है कि और परिणाम एक पूर्ण संख्या है।

आप अलग अलग सूत्र का उपयोग कर सकते हैं:

width2 = (right - left + 1) 

लेकिन इस गोल निर्देशांक केवल पर लागू होता है, के बाद से सबसे छोटी इकाई 1 पिक्सेल है। जीडीआई + के साथ काम करते समय एंटी-एलियासिंग का उपयोग करते समय, इस तथ्य से अवगत रहें कि बिंदु शून्य आकार है और पिक्सल के केंद्र में है (यह पूरे पिक्सेल नहीं है)।

+4

एंटीअलाइजिंग कोई फर्क नहीं पड़ता। असली कारण यहां वर्णित है: http://social.msdn.microsoft.com/Forums/en-US/a170efaf-829a-4cf1-b854-351938be24ae/drawrectangle-method-creates-oversize-rectangle?forum=vblanguage – Spook

+0

एंटीअलाइजिंग फर्क पड़ता है। यह पूरी तरह से मेरी आंखें खोली। इसके अलावा, यह मुझे एहसास हुआ कि F5Rx द्वारा FillRectangle को पारित आयत को फुलाकर अक्सर मैं क्या करना चाहता हूं। फ़ोरम पर उल्लिखित कारण केवल परिणाम है। एंटी-एलाइजिंग के साथ, पथ पर पिक्सेल दो बार खींचा जाएगा जिसे 50% अस्पष्टता पर दो बार खींचा जाएगा, इस प्रकार सही परिणाम भी प्रस्तुत किया जाएगा। –

1

आपके प्रश्न में दोनों ग्राफिक्स विधियों में आयताकार ऊपरी बाईं ओर (x, y) और निचले दाएं में (x + width - 1, y + height - 1) से घिरा हुआ है। यह निचले दाएं बिंदु की बजाय चौड़ाई और ऊंचाई निर्दिष्ट करने का एक परिणाम है।

जब आप दो बिंदुओं से चौड़ाई और ऊंचाई की गणना कर रहे हैं, तो आपको अंतर में 1 जोड़कर मूल पिक्सेल को शामिल करना याद रखना होगा।

उदाहरण के लिए, कहें कि आप बिंदु (5, 5) से बिंदु (10, 20) से आयताकार भरना चाहते हैं। आयताकार की चौड़ाई 6, 5 नहीं है। आयताकार की ऊंचाई 16 है, 15. नहीं।

+1

धन्यवाद, लेकिन यह पूरी सच्चाई प्रतीत नहीं होता है: DrawRectangle और FillRectangle अलग-अलग व्यवहार करते हैं: FillRectangle (ब्रश, 0,0,1,1) का उपयोग करते समय, एक एकल बिंदु खींचा जाता है, DrawRectangle (पेन, 0,0,1, 1) एक आयत खींचता है जो 2 से 2 पीएक्स होता है। यह कुछ हद तक विषम (आईएमओ) है और मुझे आश्चर्य है, अगर इस व्यवहार के लिए कुछ गहरा कारण है :) ... – MartinStettner

+0

ड्राइंग दिनचर्या में एक quirk हो सकता है। मैंने बस एक आयताकार के पीछे गणित समझाया। –

-1

व्यवहार में अंतर कुछ हद तक काउंटर अंतर्ज्ञानी तथ्य के कारण है कि ये दो एल्गोरिदम पूरी तरह से अलग-अलग चीजें करते हैं।

DrawRectangle बॉक्स के आकार में चार पंक्तियां खींचता है। FillRectangle भरा पिक्सल के डब्ल्यू * एच क्लंप का उत्पादन करता है। इससे व्यवहार में अंतर के कारण को देखना आसान है। समानता की धारणा की गलतता। चार लाइनों को रेखांकित करना पिक्सल के एक बॉक्स जैसा क्लंप बनाने से काफी अलग है।

+1

यह सवाल का जवाब नहीं देता है। इस समस्या को डेवलपर की बजाय उपयोगकर्ता दृश्य से देखने का प्रयास करें। Graphics.DrawRectangle विधि में मदद करता है कि तीसरा और चौथा पैरामीटर परिणामी ज्यामितीय आकार की चौड़ाई और ऊंचाई है। http://msdn.microsoft.com/en-us/library/x6hb4eba.aspx – truthseeker

+0

प्वाइंट इस तथ्य में निहित है कि गणितीय किनारों पिक्सल के केंद्र से गुज़र रहे हैं क्योंकि लिबर सही तरीके से इंगित करता है। – truthseeker

संबंधित मुद्दे