Python PIL - изменение цветового профиля на непомеченный RGB на обрезку, масштабирование и сохранение
Невозможно понять, почему профиль документа изменяется на урожай, масштабируется и сохраняется с помощью PIL. Протестировали с изображением, имеющим sRGB в качестве цветового профиля, и после того, как он имеет непомеченный RGB.
def scale(self, image):
images = []
image.seek(0)
try:
im = PIL.open(image)
except IOError, e:
logger.error(unicode(e), exc_info=True)
images.append({"file": image, "url": self.url, "size": "original"})
for size in IMAGE_WEB_SIZES:
d = cStringIO.StringIO()
try:
im = crop(image, size["width"], size["height"])
im.save(d, "JPEG")
images.append({"file": d, "url": self.scale_url(size["name"]), "size": size})
except IOError, e:
logger.error(unicode(e), exc_info=True)
pass
return images
Я пытаюсь получить PIL, чтобы сохранить масштабированную версию с тем же цветовым профилем, что и исходное изображение.
EDIT: в соответствии с этим должно быть возможно http://comments.gmane.org/gmane.comp.python.image/3215, но по-прежнему не работает для меня с использованием PIL 1.1.7
Ответы
Ответ 1
PIL имеет функцию для чтения icc_profile, а также способ сохранения с помощью icc_profile. Итак, я сделал это, чтобы открыть файл, чтобы получить файл icc_profile:
try:
im1 = PIL.open(image)
icc_profile = im1.info.get("icc_profile")
И добавьте его в файл снова при сохранении:
im.save(d, "JPEG", icc_profile=icc_profile)
И полный код:
def scale(self, image):
images = []
image.seek(0)
try:
im1 = PIL.open(image)
icc_profile = im1.info.get("icc_profile")
except IOError, e:
logger.error(unicode(e), exc_info=True)
images.append({"file": image, "url": self.url, "size": "original"})
for size in IMAGE_WEB_SIZES:
d = cStringIO.StringIO()
try:
im = crop(image, size["width"], size["height"])
im.save(d, "JPEG", icc_profile=icc_profile)
images.append({"file": d, "url": self.scale_url(size["name"]), "size": size})
except IOError, e:
logger.error(unicode(e), exc_info=True)
pass
return images
Я тестировал как с тегами (с профилем icc), так и с неподписанными jpeg-изображениями.
Ответ 2
Обновление: Не обращайте внимания на этот ответ, @Christoffer answer является правильным. Как оказалось, load
не делал никаких преобразований, профиль ICC просто сохранялся где-то в другом месте.
Я не думаю, что любая из этих операций меняет цветовой профиль, но преобразование выполняется прямо на load
. После открытия этого образца, используя последнюю версию PIL (1.1.7 в Windows XP), она немедленно преобразуется в RGB:
>>> from PIL import Image
>>> Image.open('Flower-sRGB.jpg')
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=600x450 at 0xD3D3F0>
Если я попытаюсь сохранить его обратно так, как он есть (без изменения чего-либо), некоторое качество теряется. Если я использую формат OTOH без потерь, получившееся изображение выглядит хорошо для меня:
>>> im = Image.open('Flower-sRGB.jpg')
>>> im.save("Flower-RBG.jpg")
>>> im.save("Flower-RBG.png")
Попытка конвертировать результирующее изображение обратно в sRGB не работала:
>>> im = Image.open('Flower-sRGB.jpg').convert('CMYK')
>>> im
<PIL.Image.Image image mode=CMYK size=600x450 at 0xD73F08>
>>> im.save("Flower-CMYK.png")
>>> im = Image.open('Flower-sRGB.jpg').convert('sRGB')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\PIL\Image.py", line 702, in convert
im = im.convert(mode, dither)
ValueError: conversion from RGB to sRGB not supported
Я считаю, что сохранение в sRGB потребует некоторой внешней библиотеки, например pyCMS или LittleCMS. Я сам их не пробовал, но здесь учебник (используя последний инструмент), который выглядит многообещающим. Наконец, здесь дискуссионный поток об одной и той же проблеме, с которой вы сталкиваетесь (сохраняя цветовой профиль без изменений при загрузке/сохранении), надеюсь, это может дать вам еще несколько указателей.