Quality of a Saved Jpg in C#

Quality of a saved JPG in C#

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

This example requires an image file named TestPhoto.jpg located at 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;
}

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

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

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)

Losing image quality in c# using Image class (reduces amount of colors)

System.Drawing has poor support for 8-bit images. When converting from 24 or 32-bit images to 8-bit; it'll always use a fixed default color palette. That default color palette only contains 16 shades of grey, the other entries are various colors.

Do you have the same problem when saving as '.bmp'? If yes, then the conversion to the 8-bit format already happened earlier, you'll have to figure out where your program does that and fix the issue there.
If it's only the tiff encoder that converts to 8-bit, you'll have to do the 8-bit conversion in a separate step first. Create an 8-bit image, fill Image.Palette with a gray-scale palette, and then copy the bitmap data over.

But System.Drawing has poor support for 8-bit images, and several methods (e.g. SetPixel) will just throw InvalidOperationException when dealing with such images. You will probably have to use unsafe code (with LockBits etc.) to copy the bitmap data. If I were you, I'd look if there are alternative graphics libraries you could use.

c#: reduced image quality when saving JPEG at 100% quality

JPEG, being a lossy format introduces loss on every save. It is also particularly bad at compressing sharp edges. According to this MSDN article, you're setting the image quality correctly. You can play with the other settings if you want to try and optimize the image quality, as I don't know how you came up with the ScanMethod and RenderMethod. However, the best way in my opinion is to use a lossless format (PNG, TIFF, etc).

Update

It appears that this is due to the bad GDI+ JPEG encoder. More on it on the MSDN forums. The conclusion is - use a third party imaging library, there are plenty free ones out there.

C# Saving Image Bad Quality

I have used this GetEncoder method:

private ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}

Invoked it with GetEncoder(ImageFormat.Jpeg); and removed the references to pictureBoxBackground1&2 (otherwise it won't build) and the end result is high quality as far as I can tell.

High quality JPEG compression with c#

It looks like you're setting the quality to 100%. That means that there will be no compression.

If you change the compression level (80, 50, etc.) and you're unsatisifed with the quality, you may want to try a different image library. LEADTools has a good (non-free) engine.

UPDATE: As a commenter mentioned, 100% quality still does not mean lossless compression when using JPEG. Loading the image, doing something to it, and then saving it again will ultimately result in image degradation. If you need to alter and save an image without losing any of the data you need to use a lossless format such as TIFF, PNG or BMP. I'd go with compressed TIFF (since it's still lossless even though it's compressed) or PNG.

Change image quality on the fly

You can save your bitmap directly to MemoryStream and do whatever you want with it. Your encoder will be applied to image inside this stream. Instead of passing file path as first parameter of Save method just pass instance of MemoryStream. If I remember correctly there's also a way to pass this stream directly as a response to browser.

using(var ms = new MemoryStream()) 
{
bmp1.Save(ms, jgpEncoder, myEncoderParameters);
var bmp2 = new BitMap(ms);
//do whatever you want with this image
}

Keep in mind to use using statment or dispose method for sfream to avoid memory leak.

More details here:
https://learn.microsoft.com/en-us/dotnet/api/system.drawing.bitmap?view=netframework-4.7.2



Related Topics



Leave a reply



Submit