0

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)

devpelux
  • 2,492
  • 3
  • 18
  • 38

1 Answers1

0

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.

AndyP
  • 26
  • 4
  • This goes a bit too far imo. Only the anti-aliasing pixels need to be brought in; the pen width is already taken care of with PenAlignment.Inset.. So rect.Inflate(-1, -1); should do.. – TaW May 29 '18 at 06:51
  • But I think the problem is that @FirestormXYZ cannot use PenAlignment.Inset because antialiasing does not work correctly in that case. So "inset" drawing needs to be simulated by setting PenAlignment to 'Center' and shrinking the bounding box by 1/2 pen width. – AndyP May 29 '18 at 22:09