當你要用.NET Framework對JPEG進行壓縮率的最佳化時,你會大量的使用到System.Drawing.Imaging這個命名空間裡面的各式類別,但是當你網路爬文爬到MSDN裡面的文章How to: Set JPEG Compression Level時,你會發現他的Sample Code裡面有一個很詭異的函式(或者是方法),他的名字叫GetEncoder()。
說是眼盲也好,說是命名空間惹的禍也好,總之在找資料的當下,很多程式設計師沒有辦法在當下得知GetEncoder()表達的意思是什麼,答案其實就寫在MSDN該頁面的下方。
private void VaryQualityLevel() { // Get a bitmap. Bitmap bmp1 = new Bitmap(@"c:\TestPhoto.jpg"); ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg); // Create an Encoder object based on the GUID // for the Quality parameter category. System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality; // Create an EncoderParameters object. // An EncoderParameters object has an array of EncoderParameter // objects. In this case, there is only one // EncoderParameter object in the array. EncoderParameters myEncoderParameters = new EncoderParameters(1); EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 50L); myEncoderParameters.Param[0] = myEncoderParameter; bmp1.Save(@"c:\TestPhotoQualityFifty.jpg", jgpEncoder, myEncoderParameters); myEncoderParameter = new EncoderParameter(myEncoder, 100L); myEncoderParameters.Param[0] = myEncoderParameter; bmp1.Save(@"c:\TestPhotoQualityHundred.jpg", jgpEncoder, myEncoderParameters); // Save the bitmap as a JPG file with zero quality level compression. myEncoderParameter = new EncoderParameter(myEncoder, 0L); myEncoderParameters.Param[0] = myEncoderParameter; bmp1.Save(@"c:\TestPhotoQualityZero.jpg", jgpEncoder, myEncoderParameters); }
private ImageCodecInfo GetEncoder(ImageFormat format) { ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); foreach (ImageCodecInfo codec in codecs) { if (codec.FormatID == format.Guid) { return codec; } } return null; }
下面這些程式碼是我自己之前眼盲沒有看到,翻了很多網路文章才去推測出來的寫法。只不過MSDN的寫法是用物件ID比對,我寫的寫法是用字串比對。這對於不會用ImageFormat.Jpeg比對的人來說,下面這段程式碼或者多有幫助。
/// <summary> /// 尋訪編碼器 /// </summary> /// <param name="cTemp">編碼器字串</param> /// <returns>回傳編碼器(Codec)</returns> private System.Drawing.Imaging.ImageCodecInfo getEncoder(string cTemp) { System.Drawing.Imaging.ImageCodecInfo[] oCoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders(); foreach (var oCoder in oCoders) { //如果有找到Codec的話,就直接將編碼器傳回 if (oCoder.MimeType.ToLower() == cTemp.ToLower()) { return oCoder; } } //如果沒有找到任何的Codec的話,就傳回null return null; }
結論:下次看MSDN要捲到最下面,一定要確定人家下面已經沒有Sample Code了,這樣可以省下自己大量的時間。與透過網路找到我這篇文章的人共勉之。
System.Drawing.Imaging GetEncoder Encoder JPEGCompressionLevel