.net 图像缩放质量的讨论

我很早以前就完成了一个通用类来处理.net中的图片缩放和水印等处理,说实话,我从没关注过其中的画质问题。直到最近,终于有人给我指出来程序生成的图片质量不高(他们总是把图片放大到200%,300%来查看细节 face32.gif)。
原图如下:
c.jpg

现在要缩放使高固定在750px

1. 最早的相关代码:
Bitmap img = new Bitmap(object_width, object_height);
img.SetResolution(72f, 72f);            
Graphics gdiobj = Graphics.FromImage(img);
gdiobj.CompositingQuality = CompositingQuality.HighQuality;
gdiobj.SmoothingMode = SmoothingMode.HighQuality;
gdiobj.InterpolationMode = InterpolationMode.HighQualityBicubic;
gdiobj.PixelOffsetMode = PixelOffsetMode.HighQuality;
gdiobj.FillRectangle(new SolidBrush(Color.White), 0, 0,
                object_width, object_height);
Rectangle destrect = new Rectangle(0, 0,
                object_width, object_height);
gdiobj.DrawImage(this.original_image, destrect, 0, 0, actual_width,
                actual_heigh, GraphicsUnit.Pixel);
img.Save(outputfilename, System.Drawing.Imaging.ImageFormat.Jpeg);
强制以72px分辨率来生成jpeg图像,结果用大家的话来说“惨不忍睹”,以下是这张图片,大小大概100多k
c_t.jpg
从局部细节上可以看出模糊。

2.先跳过网络上常用的GetThumbnailImage方法(最后讨论),我先强制生成更高质量的格式呢(比如png和bmp,我这里用png生成),只要修改最后一行代码:
Bitmap img = new Bitmap(object_width, object_height);
img.SetResolution(72f, 72f);            
Graphics gdiobj = Graphics.FromImage(img);
gdiobj.CompositingQuality = CompositingQuality.HighQuality;
gdiobj.SmoothingMode = SmoothingMode.HighQuality;
gdiobj.InterpolationMode = InterpolationMode.HighQualityBicubic;
gdiobj.PixelOffsetMode = PixelOffsetMode.HighQuality;
gdiobj.FillRectangle(new SolidBrush(Color.White), 0, 0,
                object_width, object_height);
Rectangle destrect = new Rectangle(0, 0,
                object_width, object_height);
gdiobj.DrawImage(this.original_image, destrect, 0, 0, actual_width,
                actual_heigh, GraphicsUnit.Pixel);
img.Save(outputfilename, System.Drawing.Imaging.ImageFormat.Png);
c_medium_old.png
画质和.net的GetThumbnailImage质量差不多,但是看看大小会昏死1.54mb,而且无论你怎么定义分辨率,都只有72px

3.看来用png是不行了,不然加载时间太长。现在我从原图中取得图片信息再给新图片导进去
Bitmap img = new Bitmap(object_width, object_height);
img.SetResolution(72f, 72f);            
Graphics gdiobj = Graphics.FromImage(img);
gdiobj.CompositingQuality = CompositingQuality.HighQuality;
gdiobj.SmoothingMode = SmoothingMode.HighQuality;
gdiobj.InterpolationMode = InterpolationMode.HighQualityBicubic;
gdiobj.PixelOffsetMode = PixelOffsetMode.HighQuality;
gdiobj.FillRectangle(new SolidBrush(Color.White), 0, 0,
                object_width, object_height);
Rectangle destrect = new Rectangle(0, 0,
                object_width, object_height);
gdiobj.DrawImage(this.original_image, destrect, 0, 0, actual_width,
                actual_heigh, GraphicsUnit.Pixel);
System.Drawing.Imaging.EncoderParameters ep = new System.Drawing.Imaging.EncoderParameters(1);
            ep.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100);
System.Drawing.Imaging.ImageCodecInfo ici = GetEncoderInfo("image/jpeg");
if (ici != null)
{
       img.Save(outputfilename, ici, ep);
}
else
{
        img.Save(outputfilename, System.Drawing.Imaging.ImageFormat.Jpeg);
}
c_medium_old_info.jpg
画质几乎没有得到损失,而且大小成为了568k,这个可以认为是最好的解决方案了。

4.最后再看一个网络上来的方法,这个方法不使用drawimage方法来缩放图像,而是使用.net的缩略图方法来创建(GetThumbnailImage)。
System.Drawing.Image thumbnailImage =
                original_image.GetThumbnailImage(object_width, object_height, new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero);
System.Drawing.Bitmap img = new System.Drawing.Bitmap(thumbnailImage);
System.Drawing.Imaging.EncoderParameters ep = new System.Drawing.Imaging.EncoderParameters(1);
            ep.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100);
System.Drawing.Imaging.ImageCodecInfo ici = GetEncoderInfo("image/jpeg");
if (ici != null)
{
                img.Save(outputfilename, ici, ep);
}
else
{
                img.Save(outputfilename, System.Drawing.Imaging.ImageFormat.Jpeg);
}
c_medium_thumb.jpg
产生的图像547k,画质和方法3几乎一样,局部色彩上略有不同。
但这个函数却有一个致命的问题,如果对下面这张图进行处理的话,产生的结果是会吐血的,画质不是一般的糟糕。
437392751_b774f270ae_o.jpg
到底是哪里出了问题呢,我们看下GetThumbnailImage方法在msdn上的说明:
如果 Image 包含一个嵌入式缩略图像,则此方法会检索嵌入式缩略图,并将其缩放为所需大小。如果 Image 不包含嵌入式缩略图像,此方法会通过缩放主图像创建一个缩略图像。
问题在于原照片上上,如果拿exif工具查看这张照片,你会发觉有一张160 * 120的缩略图包含在这张图片里面,因此GetThumbnailImage直接得到了这张缩略图返回了,而且因为我们要定义了大小,他实际上是把那张160*120的缩略图放到我指定的大小后返回了。画质我们可以想象的到时多糟糕。

参考我在csdn上的帖子:

转载于:https://www.cnblogs.com/adow/archive/2007/10/05/914573.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值