Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What quality level does Image.Save() use for jpeg files?

I just got a real surprise when I loaded a jpg file and turned around and saved it with a quality of 100 and the size was almost 4x the original. To further investigate I open and saved without explicitly setting the quality and the file size was exactly the same. I figured this was because nothing changed so it's just writing the exact same bits back to a file. To test this assumption I drew a big fat line diagonally across the image and saved again without setting quality (this time I expected the file to jump up because it would be "dirty") but it decreased ~10Kb!

At this point I really don't understand what is happening when I simply call Image.Save() w/out specifying a compression quality. How is the file size so close (after the image is modified) to the original size when no quality is set yet when I set quality to 100 (basically no compression) the file size is several times larger than the original?

I've read the documentation on Image.Save() and it's lacking any detail about what is happening behind the scenes. I've googled every which way I can think of but I can't find any additional information that would explain what I'm seeing. I have been working for 31 hours straight so maybe I'm missing something obvious ;0)

All of this has come about while I implement some library methods to save images to a database. I've overloaded our "SaveImage" method to allow explicitly setting a quality and during my testing I came across the odd (to me) results explained above. Any light you can shed will be appreciated.

Here is some code that will illustrate what I'm experiencing:

string filename = @"C:\temp\image testing\hh.jpg"; string destPath = @"C:\temp\image testing\";  using(Image image = Image.FromFile(filename)) {     ImageCodecInfo codecInfo = ImageUtils.GetEncoderInfo(ImageFormat.Jpeg);      //  Set the quality     EncoderParameters parameters = new EncoderParameters(1);      // Quality: 10     parameters.Param[0] = new EncoderParameter(         System.Drawing.Imaging.Encoder.Quality, 10L);     image.Save(destPath + "10.jpg", codecInfo, parameters);      // Quality: 75     parameters.Param[0] = new EncoderParameter(         System.Drawing.Imaging.Encoder.Quality, 75L);     image.Save(destPath + "75.jpg", codecInfo, parameters);      // Quality: 100     parameters.Param[0] = new EncoderParameter(         System.Drawing.Imaging.Encoder.Quality, 100L);     image.Save(destPath + "100.jpg", codecInfo, parameters);      //  default     image.Save(destPath + "default.jpg", ImageFormat.Jpeg);      //  Big line across image     using (Graphics g = Graphics.FromImage(image))     {         using(Pen pen = new Pen(Color.Red, 50F))         {             g.DrawLine(pen, 0, 0, image.Width, image.Height);         }     }      image.Save(destPath + "big red line.jpg", ImageFormat.Jpeg); }  public static ImageCodecInfo GetEncoderInfo(ImageFormat format) {     return ImageCodecInfo.GetImageEncoders().ToList().Find(delegate(ImageCodecInfo codec)     {         return codec.FormatID == format.Guid;     }); } 
like image 903
scubasteve Avatar asked Oct 18 '10 08:10

scubasteve


People also ask

What is the default quality level for saving image as JPEG?

By default, Sirv outputs JPEGs at 80%.

Which image quality is JPEG?

JPEG images use a lossy compression algorithm. This algorithm trades quality for compression. A low-quality image results in a smaller JPEG file; a high-quality image generates a relatively large file. This is different from lossless image formats, such as PNG, BMP, and PPM, where the quality never degrades.

What is the highest JPEG quality?

More at the JPG link at page bottom. TIF is lossless (including LZW compression option), which is considered the highest quality format for commercial work.


1 Answers

Using reflector, it turns out Image.Save() boils down to the GDI+ function GdipSaveImageToFile, with the encoderParams NULL. So I think the question is what the JPEG encoder does when it gets a null encoderParams. 75% has been suggested here, but I can't find any solid reference.

EDIT You could probably find out for yourself by running your program above for quality values of 1..100 and comparing them with the jpg saved with the default quality (using, say, fc.exe /B)

like image 70
Ohad Schneider Avatar answered Oct 15 '22 05:10

Ohad Schneider