Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建具有圆角的图像缩略图_C#_.net_Gdi+ - Fatal编程技术网

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;