How can I detect if the JPG is AdobeRGB and if it is convert it in python to sRGB JPG.
If that is possible in PIL, that would be great. Thank you.
I had the same problem, I tested all answers and get wrong color in final image. @DrMeers All matrixes I've tried gave wrong result in red and blacks, so here is my solution:
The only way I found out is to read profile from image and convert using ImageCms.
from PIL import Image
from PIL import ImageCms
import tempfile
def is_adobe_rgb(img):
return 'Adobe RGB' in img.info.get('icc_profile', '')
def adobe_to_srgb(img):
icc = tempfile.mkstemp(suffix='.icc')[1]
with open(icc, 'w') as f:
f.write(img.info.get('icc_profile'))
srgb = ImageCms.createProfile('sRGB')
img = ImageCms.profileToProfile(img, icc, srgb)
return img
img = Image.open('testimage.jpg')
if is_adobe_rgb(img):
img = adobe_to_srgb(img)
# then do all u want with image. crop, rotate, save etc.
I think this method can be used to any color profile, but not tested.
Thanks for the spec link martineau, I've put some working PIL
code together with functions that detect the presence of a Adobe RGB ICC profile within an Image
, and convert the colorspace to sRGB.
adobe_to_xyz = (
0.57667, 0.18556, 0.18823, 0,
0.29734, 0.62736, 0.07529, 0,
0.02703, 0.07069, 0.99134, 0,
) # http://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf
xyz_to_srgb = (
3.2406, -1.5372, -0.4986, 0,
-0.9689, 1.8758, 0.0415, 0,
0.0557, -0.2040, 1.0570, 0,
) # http://en.wikipedia.org/wiki/SRGB
def adobe_to_srgb(image):
return image.convert('RGB', adobe_to_xyz).convert('RGB', xyz_to_srgb)
def is_adobe_rgb(image):
return 'Adobe RGB' in image.info.get('icc_profile', '')
# alternative solution if happy to retain profile dependency:
# http://stackoverflow.com/a/14537273/284164
# icc_profile = image.info.get("icc_profile")
# image.save(destination, "JPEG", icc_profile=icc_profile)
(I used these to create a Django easy-thumbnails processor function):
def preserve_adobe_rgb(image, **kwargs):
if is_adobe_rgb(image):
return adobe_to_srgb(image)
return image
To program this yourself, you could convert pixels in the AdobeRGB colorspace to CIE XYZ, and then convert that to sRGB. PIL image
objects have a method named convert()
with the ability to apply a general matrix transformation to all the pixels in an image (see the section on Image.convert() in the the online documentation of the PIL Image module -- note the example showing the matrix values needed for going from RGB to XYZ).
Section 4.3.4 in the AdobeRGB1998 .pdf spec shows a matrix for transforming XYZ into RGB.
I'm not sure how to detect the colorspace of JPG images. I recall reading something about ICC xml profiles being attached to the end of the file (and a problem arising when there was more than one), but I can't vouch for its validity. The Wikipedia article on the JPEG file format says profiles are embedded.