PIL / Pillow decode icc profile information

I am stuck with decoding / parsing ICC profile information retrieved with PIL.

Below is a test image containing the "Adobe RGB (1998)" profile.

# download the test image:
wget http://i.stack.imgur.com/62AHB.jpg

      

-

from PIL import Image
path = '62AHB.jpg'
icc = Image.open(path).info.get('icc_profile') 

      

So far so good, but I couldn't find a way to handle the returned ICC information.

The above example will return:

'\x00\x00\x020ADBE\x02\x10\x00\x00mntrRGB XYZ\x07\xcf\x00\x06\x00\x03\x00\x00\x00\x00\x00\x00acspAPPL\x00\x00\x00\x00none\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\xf6\xd6\x00\x01\x00\x00\x00\x00\xd3-ADBE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ncprt\x00\x00\x00\xfc\x00\x00\x002desc\x00\x00\x010\x00\x00\x00kwtpt\x00\x00\x01\x9c\x00\x00\x00\x14bkpt\x00\x00\x01\xb0\x00\x00\x00\x14rTRC\x00\x00\x01\xc4\x00\x00\x00\x0egTRC\x00\x00\x01\xd4\x00\x00\x00\x0ebTRC\x00\x00\x01\xe4\x00\x00\x00\x0erXYZ\x00\x00\x01\xf4\x00\x00\x00\x14gXYZ\x00\x00\x02\x08\x00\x00\x00\x14bXYZ\x00\x00\x02\x1c\x00\x00\x00\x14text\x00\x00\x00\x00Copyright 1999 Adobe Systems Incorporated\x00\x00\x00desc\x00\x00\x00\x00\x00\x00\x00\x11Adobe RGB (1998)\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00XYZ \x00\x00\x00\x00\x00\x00\xf3Q\x00\x01\x00\x00\x00\x01\x16\xccXYZ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00curv\x00\x00\x00\x00\x00\x00\x00\x01\x023\x00\x00curv\x00\x00\x00\x00\x00\x00\x00\x01\x023\x00\x00curv\x00\x00\x00\x00\x00\x00\x00\x01\x023\x00\x00XYZ \x00\x00\x00\x00\x00\x00\x9c\x18\x00\x00O\xa5\x00\x00\x04\xfcXYZ \x00\x00\x00\x00\x00\x004\x8d\x00\x00\xa0,\x00\x00\x0f\x95XYZ \x00\x00\x00\x00\x00\x00&1\x00\x00\x10/\x00\x00\xbe\x9c'

      

How can this information be decoded?

There seems to be some keys inside the data. In this case, I just need the "desc" value, which in this case will be "Adobe RGB (1998)".

Any ideas? We look forward to your feedback :)!

Test Image with Embedded Adobe RGB Profile (1998)

+3


source to share


3 answers


I am writing this as well if some people come around this way to find information on how to handle ICC color profile information in Python. The Pillow fork of the Python source PIL includes a module ImageCms

. Unfortunately the constructor for the profile requires a filename or file-like object, so we have to do it from the side viaio.BytesIO

image = Image.open('/tmp/DQ-Tool_Print_13x18cm.jpg')
icc = image.info.get('icc_profile')
f = io.BytesIO(icc)
prf = PIL.ImageCms.ImageCmsProfile(f)

      



Now prf

contains an instance of a color profile. Take a look at the docs here: https://pillow.readthedocs.io/en/4.2.x/reference/ImageCms.html#PIL.ImageCms.CmsProfile

+4


source


I don't know of a dedicated Python module that can handle ICC color profiles .

If you consider yourself adventurous, see section 6 "Requirements" of the ICC Profile Format Specification . This should help you figure out how to interpret bytes.



The Pillow test folder contains two ICC profiles, so it might be worth digging up some of your tests. You can also look at this answer which links to Little CMS , which seems to support some ICC profiles.

+1


source


I know this problem has been resolved already, but I'm just adding this because it might be helpful for people looking for a way to extract ICC profile information in Python.

As part of the jpylyzer software (of which I am the main developer), I somehow wrote Python code to extract the basic header fields of an ICC profile (this is completely independent of any external libraries). See the validate_icc function below:

https://github.com/openpreserve/jpylyzer/blob/master/jpylyzer/boxvalidator.py#L598

If you follow this link and then scroll down a bit, you will see an overview of all the properties displayed. Please note that the code does not actually read the information inside ICC tags, but you can extend it based on the ICC profile specifications .

+1


source







All Articles