Currently, I'm successfully using the Graphics
class to draw a non-rectangular clipped image (the turtle inside):
My code looks something like:
using (var g = Graphics.FromImage(image))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
using (var gfxPath = new GraphicsPath())
{
gfxPath.AddEllipse(r);
using (var region = new Region(r))
{
region.Exclude(gfxPath);
g.ExcludeClip(region);
g.DrawImage(turtleImage, r, r2, GraphicsUnit.Pixel);
}
}
}
This all works just as expected. What I do not know how to solve is to make the image border anti-aliased.
The image zoomed looks like:
I.e. the border where the image ends and the transparent "background" of the image starts is a rough cut, not a smooth alpha blending.
My question is:
Is it possible to clip a drawn image and having anti-aliasing active?
If you want to go for full blown feathering you should consider taking a look at this article:
http://danbystrom.se/2008/08/24/soft-edged-images-in-gdi/
If you want a quick and easy solution you could probably draw the image first then draw a GraphicsPath on top of it using a solid white brush with antialiasing. You would do something like this:
Rectangle outerRect = ClientRectangle;
Rectangle rect = Rectangle.Inflate(outerRect, -20, -20);
using (Image img = new Bitmap("test.jpg"))
{
g.DrawImage(img, outerRect);
using (SolidBrush brush = new SolidBrush(Color.White))
using (GraphicsPath path = new GraphicsPath())
{
g.SmoothingMode = SmoothingMode.AntiAlias;
path.AddEllipse(rect);
path.AddRectangle(outerRect);
g.FillPath(brush, path);
}
}
I had the same issue with constructing a circular profile picture with a transparent background. The tactic I finally settled on was to resize the image to an arbitrary multiple (in my case 5x), do the clipping operation, then shrink it back to the original size while using SmoothingMode.AntiAlias. I get a nicely feathered edge on the picture.
Is it a hack? Yes. Is it performant? Mmm, probably not. Does it work? Perfectly!