System.Drawing.Imaging裡面的GetEncoder在哪?
當你要用.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);
}
傳說中的GetEncoder其實就寫在該頁下方
private ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
事後發現我寫的其實與MSDN雷同
下面這些程式碼是我自己之前眼盲沒有看到,翻了很多網路文章才去推測出來的寫法。只不過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了,這樣可以省下自己大量的時間。與透過網路找到我這篇文章的人共勉之。