C# 创建具有圆角的图像缩略图
我需要创建一个带有透明圆角的缩略图。在此要求之前,我使用了简单的:C# 创建具有圆角的图像缩略图,c#,.net,gdi+,C#,.net,Gdi+,我需要创建一个带有透明圆角的缩略图。在此要求之前,我使用了简单的: 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.Dra
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'如果存在,因此我可以在4个角的每个角上具有可变的圆度):
但这种方法产生了丑陋的未插值图像,带有真正参差不齐的梯度。有没有更好的方法来创建透明的缩略图,或者我可以使用一些设置来改进输出?我会先将图像复制到第二个圆角图像,然后使用它来缩小它。我写了一篇博客文章,详细解释了如何做到这一点
如果你看第一张样本图片,你会看到5),我会告诉你如何得到6)。祝你好运。我使用了一种改进的TransferChannel方法来添加掩码,它不像danbystrom的博客文章那样不安全
public static void TransferChannel(Bitmap src, Bitmap dst, ChannelARGB sourceChannel, ChannelARGB destChannel)
{
if (src.Size != dst.Size)
throw new ArgumentException();
var r = new Rectangle(Point.Empty, src.Size);
var bdSrc = src.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
var bdDst = dst.LockBits(r, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
var s = bdSrc.Stride * src.Height;
var baSrc = new byte[s];
var baDst = new byte[s];
Marshal.Copy(bdSrc.Scan0, baSrc, 0, s);
Marshal.Copy(bdDst.Scan0, baDst, 0, s);
for (var counter = 0; counter < baSrc.Length; counter += 4)
baDst[counter + (int)destChannel] = baSrc[counter + (int)sourceChannel];
Marshal.Copy(baDst, 0, bdDst.Scan0, s);
src.UnlockBits(bdSrc);
dst.UnlockBits(bdDst);
}
我使用了您的传输通道方法,但使用了我自己的函数来创建掩码位图。还有插值的问题,第一行图像是半透明的,所以我只能在角上剪下小圆弧,而不是在整个图像上画一条图形路径。
public static void TransferChannel(Bitmap src, Bitmap dst, ChannelARGB sourceChannel, ChannelARGB destChannel)
{
if (src.Size != dst.Size)
throw new ArgumentException();
var r = new Rectangle(Point.Empty, src.Size);
var bdSrc = src.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
var bdDst = dst.LockBits(r, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
var s = bdSrc.Stride * src.Height;
var baSrc = new byte[s];
var baDst = new byte[s];
Marshal.Copy(bdSrc.Scan0, baSrc, 0, s);
Marshal.Copy(bdDst.Scan0, baDst, 0, s);
for (var counter = 0; counter < baSrc.Length; counter += 4)
baDst[counter + (int)destChannel] = baSrc[counter + (int)sourceChannel];
Marshal.Copy(baDst, 0, bdDst.Scan0, s);
src.UnlockBits(bdSrc);
dst.UnlockBits(bdDst);
}
var b = new Bitmap(dataSize.Width, dataSize.Height, PixelFormat.Format32bppArgb);
using (var g = Graphics.FromImage(b))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(original, start.X, start.Y, original.Width * ratio, original.Height * ratio);
if (hasRoundedCorners)
using (var mask = CreateMask(dataSize, radius))
TransferChannel(mask, b, ChannelARGB.Blue, ChannelARGB.Alpha);
}
return b;