2
votes

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:

Yellow-116-Ravenna-7-Back-View.jpg

The small image:

Yellow-116-Ravenna-7-Back-View.jpg

The small image compressed:

Yellow-116-Ravenna-7-Back-View.jpg

The original image:

Yellow-116-Ravenna-7-Back-View.jpg

2
Sure the output format is jpeg? .BackgroundColor(Color.Transparent) hints at a transparency-supporting format, which jpeg is not. When I take the "medium" file (77.8 kB), put it in Paint.NET and resave it as jpeg with 10% encoder quality I get a 3.58 kB picture, so that works as expected. Can you upload the original 3000x3000px file?Maximilian Gerhardt
but large attached image file size is 78KB and smallest is 21KBesiprogrammer
@MaximilianGerhardt - SO does not allow me to upload the original image (or the md or sm images) as they are over 2mb. I'll try to host the images and share them.Carel
@MaximilianGerhardt - I was able to host the original images on a different site and link them in my post.Carel
@esiprogrammer - I've uploaded the original images as hosted on postimg.orgCarel

2 Answers

4
votes

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".

enter image description here

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();
0
votes

When using ImageProcessor it is possible to set an option in the processing.config

<processing preserveExifMetaData="true" fixGamma="false" interceptAllRequests="false" allowCacheBuster="true">

Setting preserveExifMetaData="false" to removes the EXIF data aswell.

You can also set the option in the ImageFactory constructor:

var imageFactory = new ImageFactory(preserveExifData:true);