在C#中保存JPG的质量

我做了一个小的C#应用​​程序来创build一个JPG格式的图像。

pictureBox.Image.Save(name,ImageFormat.Jpeg); 

该图像是成功创build的。 我input一个原始图片,做一些东西,并保存它。 然而,这个新的图片质量比原来的要低。

有没有什么办法来设定所需的质量?

以下代码示例演示如何使用EncoderParameter构造函数创buildEncoderParameter。 要运行此示例,请粘贴代码并调用VaryQualityLevel方法。

这个例子需要一个名为TestPhoto.jpg的图像文件位于c :.

 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; } 

参考: http : //msdn.microsoft.com/en-us/library/system.drawing.imaging.encoderparameter.aspx

下面是一个更加紧凑的代码块,用于保存具有特定质量的JPEG:

 var encoder = ImageCodecInfo.GetImageEncoders().First(c => c.FormatID == ImageFormat.Jpeg.Guid); var encParams = new EncoderParameters() { Param = new[] { new EncoderParameter(Encoder.Quality, 90L) } }; image.Save(path, encoder, encParams); 

或者,如果120个字符宽的线太长,

 var encoder = ImageCodecInfo.GetImageEncoders() .First(c => c.FormatID == ImageFormat.Jpeg.Guid); var encParams = new EncoderParameters(1); encParams.Param[0] = new EncoderParameter(Encoder.Quality, 90L); image.Save(path, encoder, encParams); 

确保质量是一个long否则你会得到一个ArgumentException

这是一个古老的线程,但我已经改写微软(按照达斯汀Getz的答案)是一个更有用一点 – 缩小GetEncoderInfo和在Image上扩展。 无论如何没有什么新的,但可能是有用的:

  /// <summary> /// Retrieves the Encoder Information for a given MimeType /// </summary> /// <param name="mimeType">String: Mimetype</param> /// <returns>ImageCodecInfo: Mime info or null if not found</returns> private static ImageCodecInfo GetEncoderInfo(String mimeType) { var encoders = ImageCodecInfo.GetImageEncoders(); return encoders.FirstOrDefault( t => t.MimeType == mimeType ); } /// <summary> /// Save an Image as a JPeg with a given compression /// Note: Filename suffix will not affect mime type which will be Jpeg. /// </summary> /// <param name="image">Image: Image to save</param> /// <param name="fileName">String: File name to save the image as. Note: suffix will not affect mime type which will be Jpeg.</param> /// <param name="compression">Long: Value between 0 and 100.</param> private static void SaveJpegWithCompressionSetting(Image image, string fileName, long compression) { var eps = new EncoderParameters(1); eps.Param[0] = new EncoderParameter(Encoder.Quality, compression); var ici = GetEncoderInfo("image/jpeg"); image.Save(fileName, ici, eps); } /// <summary> /// Save an Image as a JPeg with a given compression /// Note: Filename suffix will not affect mime type which will be Jpeg. /// </summary> /// <param name="image">Image: This image</param> /// <param name="fileName">String: File name to save the image as. Note: suffix will not affect mime type which will be Jpeg.</param> /// <param name="compression">Long: Value between 0 and 100.</param> public static void SaveJpegWithCompression(this Image image, string fileName, long compression) { SaveJpegWithCompressionSetting( image, fileName, compression ); } 

查看MSDN有关如何设置JPEG压缩级别的文章。

您需要使用另一个Save()重载,它接受ImageEncoder及其参数。

使用无typesGDI +样式( https://msdn.microsoft.com/en-us/library/windows/desktop/ms533845(v=vs.85).aspx )设置JPEG质量的属性看起来过度使用。

直接的方式应该是这样的:

 FileStream stream = new FileStream("new.jpg", FileMode.Create); JpegBitmapEncoder encoder = new JpegBitmapEncoder(); encoder.QualityLevel = 100; // "100" for maximum quality (largest file size). encoder.Frames.Add(BitmapFrame.Create(image)); encoder.Save(stream); 

参考: https : //msdn.microsoft.com/en-us/library/system.windows.media.imaging.jpegbitmapencoder.rotation(v= vs.110).aspx# Anchor_2

如果您使用.NET Compact Framework,则可以使用PNG无损格式,即:

 image.Save(filename, ImageFormat.Png); 

接受的社区维基答案引用了来自微软的一个例子。

不过,为了节省你们中的一些时间,我把它归结为一种本质

  • 把它包装成一个合适的方法
  • 实现了IDisposable 。 我还没有看到using (...) {在任何其他答案。 为了避免内存泄漏,最好的做法是处理所有实现IDisposable事情。

 public static void SaveJpeg(string path, Bitmap image) { SaveJpeg(path, image, 95L); } public static void SaveJpeg(string path, Bitmap image, long quality) { using (EncoderParameters encoderParameters = new EncoderParameters(1)) using (EncoderParameter encoderParameter = new EncoderParameter(Encoder.Quality, quality)) { ImageCodecInfo codecInfo = ImageCodecInfo.GetImageDecoders().First(codec => codec.FormatID == ImageFormat.Jpeg.Guid); encoderParameters.Param[0] = encoderParameter; image.Save(path, codecInfo, encoderParameters); } }