Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
941 views
in Technique[技术] by (71.8m points)

python - Does PIL image.convert("RGB") convert images to sRGB or AdobeRGB?

I want to batch convert images from various modes such as RGBa, CMYK etc to sRGB using PIL in Python.

However, I am not sure and can't find it anywhere whether

image.convert("RGB") 

converts the image to sRGB or Adobe RGB. My intuition says that it converts to sRGB.

If it converts to sRGB and I pass in Adobe RGB image to the convert function, would it successfully convert to sRGB?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

By default PIL is agnostic about color spaces (like sRGB and Adobe RGB).

As you might know, RGB is simply three 8-bit values for red, green and blue. CMYK is four 8-bit values. When you use Image.convert('RGB') it just converts each pixel to the triple 8-bit value. So it fundamentally changes the mode of how image is represented and stored.

sRGB and Adobe RGB, on the other hand, are just RGB color spaces. Basically, these are rules for how to render those three values on your monitor, printer or any other physical output device. Such rules can be added to JPEG files in form of ICC profiles by such software as Photoshop, for example. But PIL normally will not attach any ICC profile when you just use Image.save.

In order to check if your image embeds ICC profile, you can look for key 'icc_profile' in dictionary image.info like this image.info.get('icc_profile', None).

In order to save JPEG images preserving ICC profile with PIL you could use something like this:

img.save('image.jpg',
         format = 'JPEG',
         quality = 100,
         icc_profile = img.info.get('icc_profile',''))

In order to convert any RGB JPEG image from its color space to sRGB, you could use this function:

import io
from PIL import Image
from PIL import ImageCms

def convert_to_srgb(img):
    '''Convert PIL image to sRGB color space (if possible)'''
    icc = img.info.get('icc_profile', '')
    if icc:
        io_handle = io.BytesIO(icc)     # virtual file
        src_profile = ImageCms.ImageCmsProfile(io_handle)
        dst_profile = ImageCms.createProfile('sRGB')
        img = ImageCms.profileToProfile(img, src_profile, dst_profile)
    return img

So your code for conversion to single RGB color space might look like:

img = Image.open('image_AdobeRGB.jpg')
img_conv = convert_to_srgb(img)
if img.info.get('icc_profile', '') != img_conv.info.get('icc_profile', ''):
    # ICC profile was changed -> save converted file
    img_conv.save('image_sRGB.jpg',
                  format = 'JPEG',
                  quality = 100,
                  icc_profile = img_conv.info.get('icc_profile',''))

NOTE: you might want to use slightly lower quality than 100.

Example input (Adobe RGB JPEG):

Adobe RGB JPG

Example output (sRGB JPEG):

sRGB JPG


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...