我一直很难创造一个质量不差的缩略图。到目前为止,我提出的最佳代码是:
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
答案 0 :(得分:2)
我记得读过.NET有基于调色板格式的问题,比如GIF,所以我挖了几篇文章。
本文介绍如何量化(选择最佳调色板)以提高质量:http://msdn.microsoft.com/en-us/library/aa479306.aspx,如does this (badly formatted) article。
简而言之,我相信GDI +在执行调整大小时会选择一个非最佳的调色板。
PNG是基于调色板的,因此它们可能容易出现与GIF相同的问题。我不确定调色板是否更重要。
此代码在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
图像源作为调整大小功能。