可以重现Paint.NET的“调整大小图像”质量吗?

时间:2012-09-06 04:15:21

标签: c# .net image paint.net

我一直很难创造一个质量不差的缩略图。到目前为止,我提出的最佳代码是:

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);

哪个产生这个宝石:

enter image description here

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

enter image description here

哪种方式更好。我在网上找到的所有东西都指向了我上面代码的一些变化。我知道Paint.NET曾经是开源的。有谁知道他们在创建如此漂亮的调整大小功能方面做了多少魔术?如果该功能可以在C#中重现?

更新:

此示例中的原始图像是jpg

2 个答案:

答案 0 :(得分:2)

的GIF

我记得读过.NET有基于调色板格式的问题,比如GIF,所以我挖了几篇文章。

本文介绍如何量化(选择最佳调色板)以提高质量:http://msdn.microsoft.com/en-us/library/aa479306.aspx,如does this (badly formatted) article

简而言之,我相信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();
            }
        }
    }
}

答案 1 :(得分:0)

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