Конвертировать JPG из AdobeRGB в sRGB, используя PIL?

Как я могу определить, является ли JPG AdobeRGB и конвертировать ли он в python в sRGB JPG.

Если это возможно в PIL, это было бы здорово. Спасибо.

3 ответа

У меня была та же проблема, я проверил все ответы и получил неправильный цвет в конечном изображении. @DrMeers Все матрицы, которые я пробовал, дали неверный результат в красном и черном цветах, поэтому вот мое решение:

Единственный способ, который я узнал, - это прочитать профиль с картинки и конвертировать с помощью 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.

Я думаю, что этот метод может быть использован для любого цветового профиля, но не проверен.

Спасибо за ссылку спецификации martineau, я поставил некоторые рабочие PIL код вместе с функциями, которые обнаруживают наличие профиля Adobe RGB ICC в Imageи преобразовать цветовое пространство в 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://stackru.com/a/14537273/284164                                              
# icc_profile = image.info.get("icc_profile")                                             
# image.save(destination, "JPEG", icc_profile=icc_profile)

(Я использовал их для создания функции процессора Django easy-thumbnails):

def preserve_adobe_rgb(image, **kwargs):
    if is_adobe_rgb(image):
        return adobe_to_srgb(image)
    return image

Чтобы запрограммировать это самостоятельно, вы можете преобразовать пиксели в цветовом пространстве AdobeRGB в CIE XYZ, а затем преобразовать их в sRGB. PIL image объекты имеют метод с именем convert() с возможностью применения общего преобразования матрицы ко всем пикселям в изображении (см. раздел о преобразовании в онлайн-документации модуля PIL Image - обратите внимание на пример, показывающий значения матрицы, необходимые для перехода от RGB к XYZ).

Раздел 4.3.4 в спецификации AdobeRGB1998 .pdf показывает матрицу для преобразования XYZ в RGB.

Я не уверен, как определить цветовое пространство изображений JPG. Я вспоминаю, что читал что-то о профилях ICC xml, прикрепленных к концу файла (и о проблеме, возникающей, когда их было больше одного), но я не могу ручаться за ее достоверность. В статье в Википедии о формате файла JPEG говорится, что профили встроены.

Другие вопросы по тегам