.net 映像縮放品質的討論

來源:互聯網
上載者:User
我很早以前就完成了一個通用類來處理.net中的圖片縮放和浮水印等處理,說實話,我從沒關注過其中的畫質問題。直到最近,終於有人給我指出來程式產生的圖片品質不高(他們總是把圖片放大到200%,300%來查看細節)。原圖如下:

現在要縮放使高固定在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從局部細節上可以看出模糊。

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);畫質和.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);
}畫質幾乎沒有得到損失,而且大小成為了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);
}產生的映像547k,畫質和方法3幾乎一樣,局部色彩上略有不同。但這個函數卻有一個致命的問題,如果對下面這張圖進行處理的話,產生的結果是會吐血的,畫質不是一般的糟糕。到底是哪裡出了問題呢,我們看下GetThumbnailImage方法在msdn上的說明:如果 Image 包含一個嵌入式縮圖像,則此方法會檢索嵌入式縮圖,並將其縮放為所需大小。如果 Image 不包含嵌入式縮圖像,此方法會通過縮放主映像建立一個縮圖像。
問題在於原照片上上,如果拿exif工具查看這張照片,你會發覺有一張160 * 120的縮圖包含在這張圖片裡面,因此GetThumbnailImage直接得到了這張縮圖返回了,而且因為我們要定義了大小,他實際上是把那張160*120的縮圖放到我指定的大小後返回了。畫質我們可以想象的到時多糟糕。

參考我在csdn上的文章:http://community.csdn.net/Expert/topic/5425/5425099.xml?temp=.341366http://community.csdn.net/Expert/TopicView.asp?id=5400258

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.