我正在使用ASP.NET/C#/GDI+进行一些图像转换。我有一个看起来像这样的方法来制作一个矩形图像:
public static Image MakeRound(Image img)
{
Bitmap bmp = new Bitmap(img.Width, img.Height);
GraphicsPath gp = new GraphicsPath();
Graphics gr = Graphics.FromImage(bmp);
using (gp)
{
gp.AddEllipse(0, 0, img.Width, img.Height);
using (gr)
{
gr.SetClip(gp);
gr.DrawImage(img, Point.Empty);
}
}
return bmp;
}
它需要一个方形图像,然后添加一个与图像一样大的椭圆。然后我使用SetClip删除路径之外的所有内容并返回一个圆形图像。这按预期工作。
然后将返回的图像绘制到特定位置的另一个(较大的)图像上,并将得到的合成图像保存为文件。如何使用它的真实示例可以是为现有图像添加徽标或水印。以下是此操作的一些代码:
// Get backdrop image from server
string backdropPath = Server.MapPath("/img/backdrop.jpg");
System.Drawing.Image backdrop = Bitmap.FromFile(backdropPath);
// Create a graphics object to work with
Graphics gra = Graphics.FromImage(backdrop);
gra.DrawImage(MakeRound(smallerImage), new Point(50,50));
// Save the new image
backdrop.Save(saveFilePath);
唯一的问题是叠加/圆形/返回图像的边缘有点粗糙。我想让它的边缘更平滑,以便它与叠加的更大的背景图像更好地融合。
我可以使用任何抗锯齿参数吗?你认为这种平滑应该在上面的方法中完成,还是在圆形图像叠加在更大的背景上时应用?
欢迎所有指针和提示!
答案 0 :(得分:1)
您正在寻找的技术称为羽化,即:羽化边缘是应用于绘制图像边缘的一种抗锯齿形式。
在soft edges in GDI+上查看此帖子。它可能适用于您的方案。
答案 1 :(得分:0)
尝试将SmoothingMode设置为HighQuality,http://msdn.microsoft.com/en-us/library/system.drawing.graphics.smoothingmode.aspx。
还将InterpolationMode设置为HighQualityBicubic,http://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.interpolationmode.aspx。
答案 2 :(得分:0)
您可以找到以下大多数示例:
SetClip
删除不需要的图像部分但是如果您想要透明的背景,则两者都有问题:
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;
}
这不是尝试裁剪图像,而是先创建一个新的透明图像,然后在顶部绘制图像的一部分。