One of the slides of my Introduction to PDF color presentation was this page of Ducky pictures. Are all of these images of Ducky the same or different?
It’s a trick question, of course: The binary data of each image, pixel for pixel, is exactly alike. And yet if you compare individual Duckies, you can see that this one has warmer yellows, while this one’s are a bit washed out in comparison, and a couple have shadows that are almost orange and so on. What I had done was secretly replace the coffee with…no. I replaced the ICC Profile for each image of Ducky with a different profile.
Now, I’m not going to share that ugly code with you, instead I’m going to share the Somewhat Improved™ version, which now picks up more ICC profiles and doesn’t require that an image already be using an ICC profile.
There are several steps involved.
First, find an image element and extract some pertinent information such as its physical width and height (rather than its pixel width and height) and the number of color components that the image uses.
Next, we find all the compatible icc profile in our stash of icc profiles. And by compatible, I mean that the number of color components match up to what we’re looking for.
Then we create a page large enough to hold all of the image tiles we’re going to create.
Then for each profile, we are going to copy the image from the source document to a particular position on the new page, also creating an annotation which will tell us which ICC profile will be used for that image in that position.
Lastly, we are going to iterate through all of the page’s XObjects, remove the existing ColorSpace entry and replace it with a CosObject clone of an ICCBasedColorspace we instantiated with a stream containing an ICCProfile from a file.
The code equivalent of meatball surgery (“Yes, I grew up watching re-runs of M*A*S*H, why do you ask ?”). This isn’t at all the proper work-flow for specifying ICC profiles for an image, which ideally should have an ICC Profile specific to the device that took the image already embedded in the image.
But swapping different ICC profile can sometimes subtly change how the image is rendered at the edges of the color gamut and letting some colors pop while de-emphasizing others.