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?
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):
Example output (sRGB JPEG):
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With