FillRectangle和的DrawRectangle的像素行为 [英] Pixel behaviour of FillRectangle and DrawRectangle
问题描述
几乎每一个我用的时间 Graphics.DrawRectangle
或 Graphics.FillRectangle
(即 INT
版本),我似乎错过我要绘制矩形的右边和底部边框像素。
nearly every time I use Graphics.DrawRectangle
or Graphics.FillRectangle
(the int
versions) I seem to miss the pixels on the right and bottom border of the rectangle I want to draw.
什么是它的确切定义像素得到填补了
What is the exact definition of which pixels get filled by
Graphics.FillRectangle(brush,x,y,width,height)
和
Graphics.DrawRectangle(pen,x,y,width,height) // pen is one pixel width, i.e. width=0f
和是有其合乎逻辑的解释? (所以我终于可以记得的行为:) ...)
and is there a logical explanation for it? (so I can finally remember the behaviour :) ...)
修改
使用奥列格·祖克的奇妙尝试GDI + 的应用程序,我能找到的好奇的差异FillRectangle
和的DrawRectangle
:
Using Oleg Zhuk's marvelous Try GDI+ application, I was able to find a curious difference between FillRectangle
and DrawRectangle
:
FillRectangle(刷,0,0,1,1)
绘制在(0,0),这在某种程度上可以理解的一个点(它的宽度和高度的矩形一前一后全部)。
FillRectangle(brush,0,0,1,1)
draws a single dot at (0,0) which is somehow understandable (it's a rectangle with width and height one after all).
的DrawRectangle(笔,0,0,1,1)
,另一方面绘制一个小的2×2像素的矩形。
DrawRectangle(pen,0,0,1,1)
on the other hand draws a small 2 by 2 pixel rectangle.
相同的行为示出了用于其他宽度/高度的组合, DrawRectangle的
总是延伸一个像素越向左和底部(这是一个小烦人例如,当使用 ClientRectangle
属性周围画一个控制帧)
The same behaviour is shown for other width/height combinations, DrawRectangle
always extends one pixel more to the left and the bottom (which is a little annoying e.g. when using the ClientRectangle
property to draw a frame around a control)
我的第一个问题解决了(如何的,以他们的行为...)仍然存在第二个:为什么的做他们的行为这样
My first question solved (how to they behave...) there still remains the second one: Why do they behave this way?
推荐答案
这些方法可以正常工作,你就必须要考虑到的反锯齿和圆
These methods work correctly, you just have to take into account effects of anti-aliasing and rounding.
首先,开启抗锯齿看到的一切(不仅是圆形的结果):
First, turn on anti-aliasing to see everything (not only rounded result):
graphics.SmoothingMode = SmoothingMode.AntiAlias;
现在FillRectangle(10,10,10,10),会产生模糊的结果,DrawRectangle的(10,10,10,10)将是尖锐的。
Now FillRectangle(10,10,10,10) will produce blurry result and DrawRectangle(10,10,10,10) will be sharp.
模糊的结果意味着你有像素坐标离网。如果你需要调用:
The blurry result means that you have pixel coordinates off-grid. If you need to call:
graphics.FillRectangle(9.5f, 9.5f, 10, 10);
对齐网格矩形的左上角。
to align top-left corner of the rectangle on grid.
的DrawRectangle的是锋利的,因为它使用了宽度1.0笔。所以行开始在象素中心,并变为0.5个像素在两个方向上,从而填补恰好1个像素。
The DrawRectangle is sharp because it uses Pen of width 1.0. So the line starts on the pixel center and goes 0.5 pixels in both directions, thus filling exactly 1 pixel.
注意,宽度和高度计算是这样的:
Note that width and height are computed this way:
width = (right - left) = 19.5 - 9.5 = 10
height = (bottom - top) = ...
注意,19.5是右/底部的矩形也排列在网格的坐标,其结果是一个整数。
Notice that 19.5 is a right/bottom coordinate of the rectangle also aligned on the grid and the result is a whole number.
您可以使用不同的公式:
You can use different formula:
width2 = (right - left + 1)
不过,这也适用于四舍五入坐标仅,因为最小单位为1个像素。当使用GDI +工作使用抗锯齿,意识到这点的大小为零和谎言的在像素的中心事实(它不是整个像素)。
But this applies on rounded coordinates only, since the smallest unit is 1 pixel. When working with GDI+ that uses anti-aliasing, be aware of the fact that the point has zero size and lies in the center of pixel (it is not the whole pixel).
这篇关于FillRectangle和的DrawRectangle的像素行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!