[翻譯]Asp.net產生高品質縮圖

來源:互聯網
上載者:User
原文:http://www.thebrainparasite.com/post/Creating-great-thumbnails-in-ASPNET.aspx

使用ASP.NET內建的功能建立縮圖是非常方便和容易實現的。

int width = 190;
int height = 190;
Bitmap source = new Bitmap("c:\someimage.gif");
System.Drawing.Image thumb = source.GetThumbnailImage(width,height,null,IntPtr.Zero);

(31.7k)

麻煩的是,它生產的縮圖品質相對較差且產生的檔案過大。該方法產生的縮圖往往看起來非常汙濁,或許很多情況下這對你所需要的來說已經足夠好。

一個選擇

我常用的一個方法是使用 System.Drawing.Graphics 庫 重畫映像,這實現起來非常簡單,但是卻有非常好的效果。下面是我用來產生縮圖的一個樣本函數

public static Bitmap CreateThumbnail(Bitmap source, int thumbWi, int thumbHi, bool maintainAspect)
        {
            // return the source image if it's smaller than the designated thumbnail
            if (source.Width < thumbWi && source.Height < thumbHi) return source;

            System.Drawing.Bitmap ret = null;
            try
            {
                int wi, hi;

                wi = thumbWi;
                hi = thumbHi;

                if (maintainAspect)
                {
                    // maintain the aspect ratio despite the thumbnail size parameters
                    if (source.Width > source.Height)
                    {
                        wi = thumbWi;
                        hi = (int)(source.Height * ((decimal)thumbWi / source.Width));
                    }
                    else
                    {
                        hi = thumbHi;
                        wi = (int)(source.Width * ((decimal)thumbHi / source.Height));
                    }
                }

                // original code that creates lousy thumbnails
                // System.Drawing.Image ret = source.GetThumbnailImage(wi,hi,null,IntPtr.Zero);
                ret = new Bitmap(wi, hi);
                using (Graphics g = Graphics.FromImage(ret))
                {
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.FillRectangle(Brushes.White, 0, 0, wi, hi);
                    g.DrawImage(source, 0, 0, wi, hi);
                }
            }
            catch
            {
                ret = null;
            }

            return ret;
        }

(10.5k)

這個函數是很方便的,因為的它的一個參數用來標識是否維在產生縮圖的時候維持映像的長寬比。這個縮圖魔法發生在下面的代碼中

                using (Graphics g = Graphics.FromImage(ret))
                {
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.FillRectangle(Brushes.White, 0, 0, wi, hi);
                    g.DrawImage(source, 0, 0, wi, hi);
                }

這個方法有點慢但是卻讓人難以捨棄,從下面的插圖的對比可見:

(31.7k) (10.5k)

我想說這是檔案和映像品質都非常棒的實現,但是……

我們可以做的更好

現在我門可以混入 JPEG壓縮來真正的最佳化結果, 我不想假裝完全瞭解JPEG壓縮的代碼如何工作的,但它確實扭轉了乾坤。

                //Configure JPEG Compression Engine
                System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters();
                long[] quality = new long[1];
                quality[0] = 75;
                System.Drawing.Imaging.EncoderParameter encoderParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
                encoderParams.Param[0] = encoderParam;

                System.Drawing.Imaging.ImageCodecInfo[] arrayICI = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
                System.Drawing.Imaging.ImageCodecInfo jpegICI = null;
                for (int x = 0; x < arrayICI.Length; x++)
                {
                    if (arrayICI[x].FormatDescription.Equals("JPEG"))
                    {
                        jpegICI = arrayICI[x];
                        break;
                    }
                }

這段代碼設定了儲存經過壓縮的縮圖所需的 encoderParameters 參數,quality[0] 的值設定壓縮的層級,我曾經針對某些應用設定像40這麼低的值也成功了,俺是當品質要求比較高的時候 ,我發現設定為75非常好。使用這段代碼你能夠在產生縮圖之前使用 JPEG 壓縮演算法,當儲存的時候把 encoderParamaters 作為參數,例如:

    System.Drawing.Image myThumbnail = CreateThumbnail(myBitmap,Width,Height,false);                

    //Configure JPEG Compression Engine
                System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters();
                long[] quality = new long[1];
                quality[0] = 75;
                System.Drawing.Imaging.EncoderParameter encoderParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
                encoderParams.Param[0] = encoderParam;

                System.Drawing.Imaging.ImageCodecInfo[] arrayICI = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
                System.Drawing.Imaging.ImageCodecInfo jpegICI = null;
                for (int x = 0; x < arrayICI.Length; x++)
                {
                    if (arrayICI[x].FormatDescription.Equals("JPEG"))
                    {
                        jpegICI = arrayICI[x];
                        break;
                    }
                }
    
    myThumbnail.Save(Path.Combine(SavePathThumb, fileName), jpegICI, encoderParams);
                myThumbnail.Dispose();

(2.39k)

2.39K 大小 看起來依然很棒

結論和最後比較

這是最後三張縮圖從檔案大小最大到最小的效果對比

最大 = 31.7k

未壓縮重繪 = 10.5k (67% smaller)

壓縮重繪 = 2.39k (92% smaller)

難以捨棄的結果啊,縮圖產生函數和JPEG壓縮的原始碼 在下邊 :

ThumbnailGenerator.cs (1.97 kb)

JPEGCompressionConfig.cs (969.00 bytes)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.