Как можно выполнить цветовые преобразования с профилями ICC для набора произвольных значений пикселей (не для структуры данных изображения)?
Я хотел бы преобразовать набор значений пикселей из одного профилированного цветового пространства в другое без этих значений, находящихся в файле изображения, например, скажем, в списке структур данных RGB/RGBA/CMYK/etc.
У меня есть Python и PIL, но я заинтересован в решениях в смежных средах, если это то, что нужно.
Последний PIL имеет очень хорошую поддержку LittleCMS - но нет способа передать ему что-либо, кроме изображения PIL (или устаревшего объекта pyCMS), на которое он может воздействовать.
Насколько я могу убедиться, инструмент командной строки icctrans
это входит в LittleCMS, делает что-то в этом роде, но я не могу найти какую-либо некелетную документацию по нему, и документация ссылается на это как на демонстрационный инструмент.
2 ответа
Чтобы использовать текущую версию Little CMS 2.3 с Python, я перевел lcms2.h
в lcms2consts.py
с h2py.py
скрипт, который входит в дистрибутив Python. Скрипт не переводит объявления структуры, но констант достаточно, чтобы выполнить базовые преобразования цвета с ctypes
а также lcms2
как динамическая библиотека.
В этом примере показано преобразование одного цвета из Lab с двойной точностью в 8-битный sRGB с использованием встроенных профилей. использование cmsOpenProfileFromFile(filename, 'r')
вместо файлов.
import ctypes
from ctypes import byref
from lcms2consts import *
lcms = ctypes.windll.lcms2
inprof = lcms.cmsCreateLab4Profile(0)
outprof = lcms.cmsCreate_sRGBProfile()
xform = lcms.cmsCreateTransform(inprof, TYPE_Lab_DBL,
outprof, TYPE_RGB_8,
INTENT_PERCEPTUAL, 0)
lcms.cmsCloseProfile(inprof)
lcms.cmsCloseProfile(outprof)
DblTriplet = ctypes.c_double * 3
ByteTriplet = ctypes.c_ubyte * 3
inbuf = DblTriplet(60.1,20.2,0.5)
outbuf = ByteTriplet()
lcms.cmsDoTransform(xform, byref(inbuf), byref(outbuf), 1)
print list(outbuf)
lcms.cmsDeleteTransform(xform)
Есть два способа.
Способ взлома: Чтобы повторно профилировать N цветовых структур (и / или преобразовать их между цветовыми пространствами), вы создаете изображение 1x(N+2) с
PIL.Image.new()
использоватьyourimage.load()
чтобы получить объект интерфейса с настройкой пикселей, и установить значения (0,0) - (0, N) на то, что вы получили. Установите (0, N+1) на белый и (0, N+2) на черный и преобразуйте (или преобразовайте) это изображение, используя ваши любимые файлы ICC иPIL.ImageCms.ImageCmsTransform()
, Blammo: этот объект PIL теперь ваш LUT. Прочитайте значения с помощьюimage.load()
и ты хорош.Способ истинного ботаника: вам нужно использовать Python-colormath - который отлично подходит для преобразований цветового пространства, но не для профилирования. Colormath не может читать профили ICC, поэтому либо: а) вы можете надежно проанализировать их сумасшедший двоичный формат, либо б) буквально выполнить математику. У этого парня, Брюса Линдблума, есть все данные, доступные в формате Excel, например, для всех матриц, которые вам нужны для перепрофилирования ваших LUT. Он совершенно потрясающий. Я все еще пытаюсь "просто" передать эти данные в colormath, так что да, это делает меня менее удивительным, так как я все еще пытаюсь найти этот "умный путь" во что-то, напоминающее качество производства.
Вот и ты. Это то, что я сделал до сих пор, чтобы ответить на вопрос автономных преобразований ICC LUT в стиле коммандос. Вы, ребята, srsly.