如何在任意像素值集合上使用ICC配置文件进行颜色转换?
2 个回答
有两种方法。
黑科技方法: 如果你想重新调整 N 个颜色结构(或者在不同的颜色空间之间转换),你可以用
PIL.Image.new()
创建一个 1x(N+2) 的图像,然后用yourimage.load()
获取一个可以设置像素的对象。接着,把 (0,0) 到 (0, N) 的值设置成你想要的颜色。然后把 (0, N+1) 设置成白色,(0, N+2) 设置成黑色,最后用你喜欢的 ICC 文件和PIL.ImageCms.ImageCmsTransform()
来转换(或者校正转换)这个图像。这样,你的 PIL 对象就变成了 LUT。用image.load()
获取值就可以了,搞定。真正的极客方法: 你需要使用 Python-colormath,这个工具在颜色空间转换方面很不错,但不适合做配置文件。Colormath 不能读取 ICC 配置文件,所以你要么 a) 找个可靠的方法解析它们复杂的二进制格式,要么 b) 直接做数学运算。这个 Bruce Lindbloom 提供了所有数据的 Excel 格式,比如说 你需要的所有矩阵 来重新调整你的 LUT。他真是太棒了。我还在努力把这些数据输入到 colormath 中,所以我可能没那么厉害,因为我还在试图把这个“极客方法”变成接近生产级别的东西。
就这样。这就是我到目前为止为了解决独立的、指挥官风格的 ICC LUT 转换所做的工作。你们,真的。
为了在Python中使用当前的2.3版本的Little CMS,我用Python自带的h2py.py
脚本把lcms2.h
转换成了lcms2consts.py
。这个脚本不会翻译结构体的声明,但常量的转换已经足够我们用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)