FillRectangle和的DrawRectangle的像素行为 [英] Pixel behaviour of FillRectangle and DrawRectangle

查看:188
本文介绍了FillRectangle和的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆