DrawEllipse: Antialiasing broken with PenAlignment

2019-08-24 04:44发布

As suggested by @TaW on this previous question, I setted PenAlignment.Inset to draw the circle inside the Bitmap, but this caused another problem.


I want to draw a circle on a specified Bitmap with antialiasing.

SmoothingMode.AntiAlias

The problem is that, when I use PenAlignment.Inset, the antialiasing doesn't work correctly!
Instead, with PenAlignment.Center, it works correctly...
Any suggestion to resolve this problem?

Bitmap layer = new Bitmap(80, 80);
using (Graphics g = Graphics.FromImage(layer))
{
    using (Pen p = new Pen(Color.Black, 4))
    {
        p.Alignment = PenAlignment.Inset;
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.DrawEllipse(p, new Rectangle(0, 0, layer.Width, layer.Height));
    }
}
pictureBox3.Size = new Size(100, 100);
pictureBox3.Image = layer;

correct antialiasing broken antialiasing
(Note the bugs on the left image)

1条回答
别忘想泡老子
2楼-- · 2019-08-24 05:16

Deflating the bounding rectangle by 1/2 of the pen's stroke width should solve this problem. By "deflate", I mean pull in all 4 sides towards the rectangle's center by 1/2 pen width:

float halfPenWidth = p.Width*0.5f;
g.DrawEllipse(p, new RectangleF(halfPenWidth, halfPenWidth, layer.Width - p.Width, layer.Height - p.Width));

or plugging in a hardcoded pen width of 4:

g.DrawEllipse(p, new Rectangle(2, 2, layer.Width - 4, layer.Height - 4));

Note that the full pen width must be subtracted from the rectangle's width and height in order to pull the right and bottom sides in by 1/2 pen width while keeping the rectangle centered on the same point.

Using this code with pen alignment centered, 1/2 of the stroke width will be drawn outside of the rectangle at the points where the ellipse touches the rectangle, but it will still be drawn inside the bitmap.

查看更多
登录 后发表回答