12

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

Below a test image that contains the "Adobe RGB (1998)" profile.

# download the test image:
wget https://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 could not find a way to handle returned ICC information.

The example above 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 seem to be some keys inside the data. I basically would just need the value for "desc" which is "Adobe RGB (1998)" in that case.

Any ideas? Looking forward for your inputs :) !

Test image with embeded Adobe RGB (1998) profile

ohrstrom
  • 2,890
  • 2
  • 20
  • 34

3 Answers3

15

I'm writing this also for people that came here searching for information on how to process ICC color profile information in Python.

The Pillow fork of the original PIL library for Python includes a ImageCms module. Unfortunately the constructor for a profile requires a filename or a file-like object, so we have to do it sideways via io.BytesIO

import io

from PIL import Image
from PIL import ImageCms

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

Now prf contains a color profile instance. Have a look at the docs here: https://pillow.readthedocs.io/en/stable/reference/ImageCms.html#PIL.ImageCms.CmsProfile

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
Arminius
  • 1,029
  • 7
  • 11
2

I know this issue has been solved already, but I'm just adding this because it might be of some use to people who are looking for a way to extract ICC profile information in Python.

As part of the jpylyzer software (of which I'm the main developer), I once wrote some Python code for extracting the main 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'll see an overview of all the reported properties. Note that the code does not actually read the information inside the ICC tags, but you could extend it based on the ICC profile specifications.

johan
  • 764
  • 7
  • 17
1

I am not aware of a dedicated Python module that can handle ICC color profiles.

If you feel adventurous, take a look at section 6 "Requirements" of the ICC Profile Format Specification. This should get you started on how to interpret the bytes.

Pillow's test folder contains two ICC profiles though, so perhaps it is worthwhile digging through the code of some of their tests. You might also want to look at this answer which refers to Little CMS that seems to have some ICC profile support.

Community
  • 1
  • 1
Jens
  • 8,423
  • 9
  • 58
  • 78
  • Thanks for the suggestion. We did finally solve this using an external tool [exiftool](http://owl.phy.queensu.ca/~phil/exiftool/) and extracting the icc information form a subprocess call. – ohrstrom Jun 06 '16 at 08:44