Maintain Exif Data With Sitecore Image Resizing
Maintain Exif Data With Sitecore Image Resizing
Exif or Exchangeable Image File Format is probably something you never heard of if your a back-end developer like me. We see an image, we resize the image, we call it a day. But there is a lot more going on with images then what we see with our eyes. In fact there is so much information that can be stored in an image. Check this out – https://en.wikipedia.org/wiki/Exif .
The project I was working on was very image intensive. Requirements were that an image would be uploaded to the media library in its original format and we would use max width and max height to render the image out resized. This is great for reducing size. I've seen images uploaded at 4-6 megs for a .jpg that render down to ~10k. Pair this with CDN and caching strategies and you have a very efficient image delivery system.
But there is a problem. When Sitecore does the resizing, they make a copy of the image to its resized format and ignore all the Exif data that was in the original image.
The Solution
With the help of Sitecore support, we came up with two classes to add to the getMediaStream pipeline.
The first class attaches to the getMediaStream pipeline before ResizeProcessor. It reads in the current image and saves off the PropertyItems to the arguments of the pipeline.
PropertyItem[] items = img.PropertyItems;
Everything you need to know about a picture is here.
I'm not going to post code as this is a very specialized task and there isn't a way to make a "one size fits all" solution with something like this. I'll just go over the approach that we took. So we save off all property items to the arguments custom data object. Specifically the ColorProfile item as that was a big one.
args.CustomData["ColorProfile"] = img.GetPropertyItem(34675);
The second class is attached to the getMediaStream pipeline last. This takes the saved image data out of the arguments, applies it to the newly sized image, and outputs the image as a MediaStream.
image.SetPropertyItem((PropertyItem)args.CustomData["ColorProfile"]);
How can this be matured?
This example is a specific case of maintaining a property. I can see this going two ways. First, find the properties that you need and introduce logic similar to this ColorProfile. Second, you can loop through all EXIF data that was present. I would caution this approach however as there is properties related to height, width, and sizing that would need to be vetted. A list of property ids that are to be excluded would be ideal.