I am attempting to implement an image compression function to be used on images uploaded to my website. I want to take the original image and save 3 different sizes/quality levels. For this I am using ImageProcessor.ImageFactory
. The three levels:
ISupportedImageFormat sm_format = new JpegFormat { Quality = 40 };
Size sm_size = new Size(150, 0);
ISupportedImageFormat md_format = new JpegFormat { Quality = 60 };
Size md_size = new Size(280, 0);
ISupportedImageFormat lg_format = new JpegFormat { Quality = 100 };
Size lg_size = new Size(1000, 0);
imageFactory.Load(or_directoryPath + "/" + fileName)
.Resize(sm_size)
.Format(sm_format)
.BackgroundColor(Color.Transparent)
.Save(Path.Combine(sm_directory, fileName));
// same for md and lg images
What's happening is that the medium and small images do not have the expected smaller filesize.
An example: Original image is a .jpg 3000x3000 that is 3.7MB large.
The large image size is 2.96MB The medium image size is 2.63MB The small image size is 2.62MB
I tried the following on the small image to further compress it to 10% quality:
// Encoder parameter for image quality
EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, 10);
// JPEG image codec
ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save(path, jpegCodec, encoderParams);
The end result is significantly lower quality, but the image file size is still 2.62MB
Edit: uploaded original images shared on postimg
The medium image:
The small image:
The small image compressed:
The original image:
Upon further inspection of the image, the EXIF data really is the problem with that file. It contains a section with a custom color profile, and has data stored in it with a size of about 2.64 megabytes. This can be checked by uploading the image to http://regex.info/exif.cgi and clicking the "Show ICC profile data".
Stripping that weird profile data gets rid of the extreme overhead and brings down the filesize to 348 KB at 1000x1000 px.
As you already found out yourself, you must set the preserveExifData
parameter in the constructor of the ImageFactory
object to false
to make it strip the data. Or call the default constructor as
ImageFactory imageFactory = new ImageFactory();