Quality of saved jpg in c #

I created a small C # application to create an image in .jpg format.

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

The image will be created successfully. I enter the original pic, do something with it and save it. The quality of this new drawing, however, is lower than that of the original.

Is there any way to set the desired quality?

+52
c # image-processing
Sep 27 '09 at 23:26
source share
7 answers

The following code example shows how to create an EncoderParameter using the EncoderParameter constructor. To run this example, paste the code and call the VaryQualityLevel method.

This example requires a file called TestPhoto.jpg located in the c: directory.

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

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

+69
Sep 27 '09 at 23:30
source share

Here is an even more compact piece of code for saving in JPEG format with a certain quality:

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

Or if the lines with a width of 120 characters are too long for you:

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

Make sure the quality is long or you will get an ArgumentException !

+27
Mar 23 '15 at 13:51 on
source share

This is an old thread, but I rewrote Microsoft (as per Dustin Getz's answer) to be a little more useful - shortening GetEncoderInfo and creating an extension on the image. In any case, nothing new, but may be useful:

  /// <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 ); } 
+13
Jun 01 '12 at 11:16
source share

See the MSDN article on how to set the JPEG compression level .

You need to use another backup () that accepts ImageEncoder and its parameters.

+4
Sep 27 '09 at 23:33
source share

Using the custom GDI + style ( https://msdn.microsoft.com/en-us/library/windows/desktop/ms533845(v=vs.85).aspx ) the attributes for setting the JPEG quality look redundant.

The direct path should look like this:

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

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

+4
Nov 17 '15 at 17:15
source share

If you are using the .NET Compact Framework, an alternative would be to use the lossless PNG format, i.e.:

 image.Save(filename, ImageFormat.Png); 
+2
May 13 '13 at 10:41
source share

The wiki community response that is being accepted refers to an example from Microsoft.

However, to save some time, I welded it to the point and

  • Packed in proper method
  • Implemented by IDisposable . I have not seen using (...) { in any other answers. To avoid memory leaks, it is best to use everything that implements 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); } } 
+2
Sep 14 '16 at
source share



All Articles