创建带圆角的图像缩略图
我需要创建一个带有透明圆角的缩略图。在这个要求之前,我使用了 simple:
using (var b = new Bitmap(dataSize.Width, dataSize.Height, PixelFormat.Format32bppArgb))
using (var g = Graphics.FromImage(b))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
g.DrawImage(original, 0, 0, b.Width, b.Height);
}
即使没有任何插值,它也产生了很好的结果(缩小到大约 50x50px)。现在,对于圆角,我使用了以下算法(有 4 个“if”,因此我可以在 4 个角中的每个角上具有可变的圆度):
using (var b = new Bitmap(dataSize.Width, dataSize.Height, PixelFormat.Format32bppArgb))
using (var g = Graphics.FromImage(b))
{
// set interpolation
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
// transformation to scale and shift the brush
var transform = new Matrix();
transform.Scale(ratio, ratio);
transform.Translate(start.X / ratio, start.Y / ratio);
var brush = new TextureBrush(original) { Transform = transform };
// create path for stamping the iamge
var gp = new GraphicsPath(FillMode.Winding);
if (descriptor.CornerRadiusLeftTop > 0)
gp.AddArc(descriptor.GetLeftTopCorner(b.Size), 180, 90);
else
gp.AddLine(-1, -1, -1, -1);
if (descriptor.CornerRadiusRightTop > 0)
gp.AddArc(descriptor.GetRightTopCorner(b.Size), 270, 90);
else
gp.AddLine(b.Width + 1, -1, b.Width + 1, -1);
if (descriptor.CornerRadiusRightBottom > 0)
gp.AddArc(descriptor.GetRightBottomCorner(b.Size), 0, 90);
else
gp.AddLine(b.Width + 1, b.Height + 1, b.Width + 1, b.Height + 1);
if (descriptor.CornerRadiusLeftBottom > 0)
gp.AddArc(descriptor.GetLeftBottomCorner(b.Size), 90, 90);
else
gp.AddLine(-1, b.Height + 1, -1, b.Height + 1);
// stamp the image with original
g.FillPath(brush, gp);
}
但这种方法产生了丑陋的未插值图像,具有真正的锯齿状渐变。是否有更好的方法来创建透明缩略图,或者是否有一些设置可以用来改进输出?
I need to create a thumbnail image with transparent rounded corners. Before this requirement I used the simple:
using (var b = new Bitmap(dataSize.Width, dataSize.Height, PixelFormat.Format32bppArgb))
using (var g = Graphics.FromImage(b))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
g.DrawImage(original, 0, 0, b.Width, b.Height);
}
which produced great results (for reductions to approx 50x50px) even without any interpolation. Now with the rounded corners I used the following algorithm (the 4 'if's are there so I can have variable roundness on each of the 4 corners):
using (var b = new Bitmap(dataSize.Width, dataSize.Height, PixelFormat.Format32bppArgb))
using (var g = Graphics.FromImage(b))
{
// set interpolation
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
// transformation to scale and shift the brush
var transform = new Matrix();
transform.Scale(ratio, ratio);
transform.Translate(start.X / ratio, start.Y / ratio);
var brush = new TextureBrush(original) { Transform = transform };
// create path for stamping the iamge
var gp = new GraphicsPath(FillMode.Winding);
if (descriptor.CornerRadiusLeftTop > 0)
gp.AddArc(descriptor.GetLeftTopCorner(b.Size), 180, 90);
else
gp.AddLine(-1, -1, -1, -1);
if (descriptor.CornerRadiusRightTop > 0)
gp.AddArc(descriptor.GetRightTopCorner(b.Size), 270, 90);
else
gp.AddLine(b.Width + 1, -1, b.Width + 1, -1);
if (descriptor.CornerRadiusRightBottom > 0)
gp.AddArc(descriptor.GetRightBottomCorner(b.Size), 0, 90);
else
gp.AddLine(b.Width + 1, b.Height + 1, b.Width + 1, b.Height + 1);
if (descriptor.CornerRadiusLeftBottom > 0)
gp.AddArc(descriptor.GetLeftBottomCorner(b.Size), 90, 90);
else
gp.AddLine(-1, b.Height + 1, -1, b.Height + 1);
// stamp the image with original
g.FillPath(brush, gp);
}
but this approach produced ugly un-interpolated imaged with really jagged gradients. Is there a better approach to create transparent thumbnails or are there some settings I could use to improve the output?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我写了一篇博文,详细解释了如何做到这一点。
http://danbystrom.se/2008/08/24/ soft-edged-images-in-gdi/
如果您查看第一个示例图像,您会看到 5),我将展示如何到达 6)。祝你好运。
I've written a blog post which explains exactly how to do this.
http://danbystrom.se/2008/08/24/soft-edged-images-in-gdi/
If you look at the first sample images, you're seeing 5) and I show how to arrive at 6). Good luck.
我首先将图像复制到带有圆角的第二个图像,然后使用 GetThumbnailImage 将其缩小。
I would first copy the image to second one with rounded corners, then use GetThumbnailImage to scale it down.
我使用了修改后的 TransferChannel 方法来添加掩码,这并不像 danbystrom 的博客文章中那样不安全。
我调整大小和制作圆角的方法是:
I've used a modified TransferChannel method to add mask, which is not unsafe as in blog post by danbystrom.
And my method to resize and make rounded corners is: