1

我一直很难创建质量不差的缩略图。到目前为止,我想出的最好的代码是:

Bitmap bmp = new Bitmap(width, height);
Graphics graphic = Graphics.FromImage(bmp);
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;
graphic.DrawImage(photo, 0, 0, width, height);
return imageToByteArray(bmp);

产生这个宝石:

在此处输入图像描述

如果我在 Paint.NET 中调整相同图像的大小,我会得到:

在此处输入图像描述

哪个更好。我在网上找到的所有内容都指向我上面的代码的一些变体。我知道 Paint.NET 曾经是开源的。有谁知道他们做了什么魔术来创建如此好的调整大小功能,以及该功能是否可以在 C# 中重现?

更新:

此示例中的原始图像是 jpg

4

2 回答 2

2

动图

我记得读过 .NET 在基于调色板的格式(如 GIF)方面存在问题,所以我翻了几篇文章。

本文介绍了如何量化(选择最佳调色板)以提高质量: http: //msdn.microsoft.com/en-us/library/aa479306.aspx这篇(格式错误的)文章一样。

简而言之,我相信 GDI+ 在执行调整大小时会选择非最佳调色板。

PNG

PNG 是基于调色板的,因此它们可能容易出现与 GIF 相同的问题。我不确定调色板可以更大是否重要。

JPEG 友好示例

此代码在 JPEG 上应该可以正常工作(但不能平滑地渲染 GIF)。如果您尝试它并且它使 JPEG 像素化,那么可能还有其他事情发生。

private static byte[] GetScaledImage( byte[] inputBytes, int width, int height ) {
    Image img = null;

    using( MemoryStream ms = new MemoryStream() ) {
        ms.Write( inputBytes, 0, inputBytes.Length );
        img = Image.FromStream( ms );
    }

    using( MemoryStream ms = new MemoryStream() ) {
        using( Image newImg = new Bitmap( width, height ) ) {
            using( Graphics g = Graphics.FromImage( newImg ) ) {
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImage( img, 0, 0, width, height );

                newImg.Save( ms, img.RawFormat );
                return ms.GetBuffer();
            }
        }
    }
}
于 2012-09-06T04:27:13.830 回答
0

因为Bitmap(int,int)实际上Bitmap(int,int,PixelFormat.Format32bppArgb)我认为问题出在源图像中。如果使用调色板,请尝试创建与源图像大小相同的图像的另一个中间副本,然后将该32bppArgb图像源用于调整大小功能。

于 2012-09-06T04:31:53.217 回答