An involuntary lossless image compression by Sitecore

This is a small bonus post following my post series about responsive images in Sitecore.

When you load a JPEG image in .NET into a Bitmap and then draw it on another Bitmap then you will notice that the original image is sometimes bigger than the new one. How can that be..

This is because .NET does not “draw” the Exif information from the JPEG image onto the new Bitmap.

When the Sitecore ResizeImageProcessor in the getMediaStream pipeline resizes a JPEG image then it is actually being accidently lossless compressed since the Exif information is not stored and put back on to the image when it is resized.

But this is really good stuff, right?

Yes it is. Google Page speed love it and therefore I love it.

If you run a large high quality photo site based on Sitecore then you will loose all the author information on the images when they are resized and in this one case this unintended behavior is probably not good but for all the rest of us it is all joy and happy days.

We want more..!!

What if we want Sitecore to always loss-less compress JPEG images just as the default behavior also for images which are delivered in full size.

Well here is how that is done in a primitive fashion where we simply imitate the involuntary behavior of the ResizeImageProcessor (and my own processors from my previous posts).

I should first note  that decoding and re-encoding an image might hurt the quality. I will dare to argue that the quality degradation in 99.999 % cases will not be visible at all for images shown on web pages. If image quality is paramount then do not use this approach. 

The code is really simple. We start out with a new processor for the getMediaStream pipeline.

To prevent unnecessary resource usage we perform a pragmatic check on the querystring to see if it contains anything. Presuming that values in the querystring anyway would result in a re-encoding of the image. This check could instead look specifically for query keys which triggers an image re-encoding such as w, h, etc.

Then we write our service class which creates a bitmap from the media Stream and then saves the bitmap in a MemoryStream.

Finally we write the include configuration.

As always Sitecore caches the output of the getMediaStream pipeline so the resource consumption is not considered. This is of course under the presumption that Sitecore media cache is not disabled or for some weird reason unreliable.

That was it. I hope some day that Sitecore will make it a standard setting or even better a standard Site setting if all images from the media lib should be losslessly compressed. PNG’s as well.

Avatar photo

Anders Laub Christoffersen

Anders has been working with Sitecore for over a decade and has in this time been the lead developer and architect on several large scale enterprise solutions all around the world. Anders was appointed the title of Sitecore Technical MVP in 2014 and has been re-appointed the title every year since then.