目前,我已成功使用Graphics
class绘制非矩形剪裁图像(里面的乌龟):
我的代码类似于:
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);
}
}
}
这一切都与预期一样有效。我不知道如何解决的问题是使图像边框消除锯齿。
缩放的图像看起来像:
即。图像结束的边界和图像的透明“背景”开始是粗剪,而不是平滑的alpha混合。
我的问题是:
是否可以剪切绘制的图像并使抗锯齿处于活动状态?
答案 0 :(得分:6)
如果你想要完整的羽毛,你应该考虑看一下这篇文章:
http://danbystrom.se/2008/08/24/soft-edged-images-in-gdi/
如果您想要一个快速简便的解决方案,您可以先绘制图像,然后使用带有抗锯齿的纯白色画笔在其上绘制一个GraphicsPath。你会做这样的事情:
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);
}
}
答案 1 :(得分:1)
我想分享我的解决方案,该解决方案基于所选答案。 此代码将抗锯齿功能应用于边缘,将图像调整大小并将其裁剪为圆形。它还可以防止鼠标悬停或窗口调整大小时图像丢失。裁剪的图像可以轻松保存。
/// <summary>Redimensiona y recorta la imagen en forma de Circulo (con Antialias).</summary>
/// <param name="srcImage">Imagen Original a Recortar</param>
/// <param name="size">Tamaño deseado (en pixeles)</param>
/// <param name="BackColor">Color de fondo</param>
public static Image CropToCircle(System.Drawing.Image srcImage, Size size, System.Drawing.Color BackColor)
{
System.Drawing.Image Canvas = new System.Drawing.Bitmap(size.Width, size.Height, srcImage.PixelFormat);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(Canvas);
System.Drawing.Rectangle outerRect = new System.Drawing.Rectangle(-1, -1, Canvas.Width + 1, Canvas.Height + 1);
System.Drawing.Rectangle rect = System.Drawing.Rectangle.Inflate(outerRect, -2, -2);
g.DrawImage(srcImage, outerRect);
using (System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(BackColor))
using (System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath())
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
path.AddEllipse(rect);
path.AddRectangle(outerRect);
g.FillPath(brush, path);
}
return Canvas;
}
用法:(所需大小为64x64像素,白色背景)
System.Drawing.Image img = System.Drawing.Image.FromFile(@"E:\Mis Documentos\Mis imágenes\ergo-proxy-fullon-fight.jpg");
System.Drawing.Image circle = Util.CropToCircle(img, new System.Drawing.Size(64,64), System.Drawing.Color.White);
if (circle != null)
{
this.picUser.Image = circle;
}
答案 2 :(得分:1)
如果您想要透明的背景,那么这里的其他答案将不起作用,因为您无法使用透明的笔刷进行绘制-它什么也没做。
我找到了其他可以做到的答案(例如,使用SetClip
),但是它没有消除锯齿的边缘。
我发现this answer可以用,但是那只不过是在拐角处而不是变成一个圆而设计。所以我修改了它。
以下是将图像裁剪为具有透明背景和抗锯齿边缘的圆的方法:
/// <summary>
/// Crop the given image into a circle (or ellipse, if the image isn't square)
/// </summary>
/// <param name="img">The image to modify</param>
/// <returns>The new, round image</returns>
private static Bitmap CropCircle(Image img) {
var roundedImage = new Bitmap(img.Width, img.Height, img.PixelFormat);
using (var g = Graphics.FromImage(roundedImage))
using (var gp = new GraphicsPath()) {
g.Clear(Color.Transparent);
g.SmoothingMode = SmoothingMode.AntiAlias;
Brush brush = new TextureBrush(img);
gp.AddEllipse(0, 0, img.Width, img.Height);
g.FillPath(brush, gp);
}
return roundedImage;
}
其他答案在图像顶部绘制背景色。相反,这将首先创建一个新的透明图像,然后在顶部绘制图像的一部分。
答案 3 :(得分:0)
我在构建具有透明背景的圆形轮廓图时遇到了同样的问题。我最终确定的策略是将图像调整为任意倍数(在我的情况下为5x),执行剪切操作,然后在使用SmoothingMode.AntiAlias时将其缩小回原始大小。我在画面上得到了很好的羽毛边缘。
是黑客吗?是。它表现得好吗?嗯,可能不是。它有用吗?完美!