Как можно выполнить цветовые преобразования с профилями 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.

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