Python imaging library 在PIL中CMYK到RGB转换期间保持颜色
我正在使用PIL处理上传的图像。不幸的是,我在从CMYK到RGB的颜色转换方面遇到了问题,因为生成的图像色调和对比度会发生变化 我怀疑它只是在做直接的数字变换。PIL,或者任何构建在它之上的东西,是否有一个Adobian虚拟证明,使用嵌入的配置文件,转换到目的地,保留数字工具,我可以用来转换 在我健康的无知和缺乏经验的情况下,这种想法突然向我袭来,使我陷入困境。我真的希望在不涉及任何复杂的颜色空间、变换和必要的数学运算的情况下完成这项工作Python imaging library 在PIL中CMYK到RGB转换期间保持颜色,python-imaging-library,color-space,Python Imaging Library,Color Space,我正在使用PIL处理上传的图像。不幸的是,我在从CMYK到RGB的颜色转换方面遇到了问题,因为生成的图像色调和对比度会发生变化 我怀疑它只是在做直接的数字变换。PIL,或者任何构建在它之上的东西,是否有一个Adobian虚拟证明,使用嵌入的配置文件,转换到目的地,保留数字工具,我可以用来转换 在我健康的无知和缺乏经验的情况下,这种想法突然向我袭来,使我陷入困境。我真的希望在不涉及任何复杂的颜色空间、变换和必要的数学运算的情况下完成这项工作 虽然我以前从未使用过它,但如果有人有经验认为它可以优雅地
虽然我以前从未使用过它,但如果有人有经验认为它可以优雅地执行此处理步骤,我也愿意使用ImageMagick。因此,我很快就遇到其他人提到它,它是最流行的颜色管理开源解决方案。我结束了对Python绑定的窥探,发现了一些关于PIL支持小CMS的旧的和表面上的概念 事实上,有人支持Little CMS,它在一个巨大的行文中提到: CMS支持:littleCMS(建议使用1.1.5或更高版本) 文档中没有参考资料,没有主题指南,谷歌没有搜索任何内容,他们的邮件列表已经关闭。。。但是通过挖掘源代码,有一个模块有很好的文档记录,并且完成了工作。希望这能把人从混乱的网络挖掘中解救出来
去给自己买块饼干…现在是2019年,事情变了。你的问题比乍一看要复杂得多。问题是,CMYK到RGB和RGB到CMYK不是一个简单的来回转换。例如,如果您在Photoshop中打开图像并在其中进行转换,则此转换有两个附加参数:源颜色配置文件和目标颜色配置文件。这些大大改变了一切!对于一个典型的用例,您可以假设RGB端为
AdobeRGB1998
,CMYK端为CoativeFogra39
。这两条附加信息向转换器阐明了如何处理输入和输出上的颜色。接下来需要的是一个转换机制,小CMS实际上是一个很好的工具。它是MIT授权的,并且(在我自己寻找了相当长的时间后),如果您确实需要python方法来转换颜色,我建议您使用以下设置:
pip安装littlecms
pip安装枕
/tests
文件夹中,您可以找到一组很好的示例。我会允许自己进行一次特殊的测试。在你得到代码之前,请让我告诉你一些关于这些颜色配置文件的事情。在Windows上,与我的情况一样,您将在Windows存储其颜色配置文件的文件夹C:\Windows\System32\spool\drivers\color
中找到一组扩展名为.icc
的文件。您只需双击相应的.icc
文件,即可从类似的网站下载其他配置文件,并将其安装到Windows上。我提供的示例依赖于这样的配置文件,Little CMS使用这些配置文件进行神奇的颜色变换。我是一名半专业的图形设计师,需要能够将颜色从CMYK转换为RGB,反之亦然,以便在InDesign中操作对象的某些脚本。我的设置是RGB:Adobe RGB 1998和CMYK:Coating FOGRA 39(这些设置是大多数书籍打印机推荐的,我在那里打印书籍)。前面提到的颜色配置文件为我生成了与Photoshop和InDesign相同的变换非常相似的结果。不过,请注意,与PS和Id为相同输入提供的颜色相比,颜色稍微有点差(大约1%)。我在想为什么
小节目:
import littlecms as lc
from PIL import Image
def rgb2cmykColor(rgb, psrc='C:\\Windows\\System32\\spool\\drivers\\color\\AdobeRGB1998.icc', pdst='C:\\Windows\\System32\\spool\\drivers\\color\\CoatedFOGRA39.icc') :
ctxt = lc.cmsCreateContext(None, None)
white = lc.cmsD50_xyY() # Set white point for D50
dst_profile = lc.cmsOpenProfileFromFile(pdst, 'r')
src_profile = lc.cmsOpenProfileFromFile(psrc, 'r') # cmsCreate_sRGBProfile()
transform = lc.cmsCreateTransform(src_profile, lc.TYPE_RGB_8, dst_profile, lc.TYPE_CMYK_8,
lc.INTENT_RELATIVE_COLORIMETRIC, lc.cmsFLAGS_NOCACHE)
n_pixels = 1
in_comps = 3
out_comps = 4
rgb_in = lc.uint8Array(in_comps * n_pixels)
cmyk_out = lc.uint8Array(out_comps * n_pixels)
for i in range(in_comps):
rgb_in[i] = rgb[i]
lc.cmsDoTransform(transform, rgb_in, cmyk_out, n_pixels)
cmyk = tuple(cmyk_out[i] for i in range(out_comps * n_pixels))
return cmyk
def cmyk2rgbColor(cmyk, psrc='C:\\Windows\\System32\\spool\\drivers\\color\\CoatedFOGRA39.icc', pdst='C:\\Windows\\System32\\spool\\drivers\\color\\AdobeRGB1998.icc') :
ctxt = lc.cmsCreateContext(None, None)
white = lc.cmsD50_xyY() # Set white point for D50
dst_profile = lc.cmsOpenProfileFromFile(pdst, 'r')
src_profile = lc.cmsOpenProfileFromFile(psrc, 'r') # cmsCreate_sRGBProfile()
transform = lc.cmsCreateTransform(src_profile, lc.TYPE_CMYK_8, dst_profile, lc.TYPE_RGB_8,
lc.INTENT_RELATIVE_COLORIMETRIC, lc.cmsFLAGS_NOCACHE)
n_pixels = 1
in_comps = 4
out_comps = 3
cmyk_in = lc.uint8Array(in_comps * n_pixels)
rgb_out = lc.uint8Array(out_comps * n_pixels)
for i in range(in_comps):
cmyk_in[i] = cmyk[i]
lc.cmsDoTransform(transform, cmyk_in, rgb_out, n_pixels)
rgb = tuple(rgb_out[i] for i in range(out_comps * n_pixels))
return rgb
def rgb2cmykImage(PILImage, psrc='C:\\Windows\\System32\\spool\\drivers\\color\\AdobeRGB1998.icc', pdst='C:\\Windows\\System32\\spool\\drivers\\color\\CoatedFOGRA39.icc') :
ctxt = lc.cmsCreateContext(None, None)
white = lc.cmsD50_xyY() # Set white point for D50
dst_profile = lc.cmsOpenProfileFromFile(pdst, 'r')
src_profile = lc.cmsOpenProfileFromFile(psrc, 'r')
transform = lc.cmsCreateTransform(src_profile, lc.TYPE_RGB_8, dst_profile, lc.TYPE_CMYK_8,
lc.INTENT_RELATIVE_COLORIMETRIC, lc.cmsFLAGS_NOCACHE)
n_pixels = PILImage.size[0]
in_comps = 3
out_comps = 4
n_rows = 16
rgb_in = lc.uint8Array(in_comps * n_pixels * n_rows)
cmyk_out = lc.uint8Array(out_comps * n_pixels * n_rows)
outImage = Image.new('CMYK', PILImage.size, 'white')
in_row = Image.new('RGB', (PILImage.size[0], n_rows), 'white')
out_row = Image.new('CMYK', (PILImage.size[0], n_rows), 'white')
out_b = bytearray(n_pixels * n_rows * out_comps)
row = 0
while row < PILImage.size[1] :
in_row.paste(PILImage, (0, -row))
data_in = in_row.tobytes('raw')
j = in_comps * n_pixels * n_rows
for i in range(j):
rgb_in[i] = data_in[i]
lc.cmsDoTransform(transform, rgb_in, cmyk_out, n_pixels * n_rows)
for j in cmyk_out :
out_b[j] = cmyk_out[j]
out_row = Image.frombytes('CMYK', in_row.size, bytes(out_b))
outImage.paste(out_row, (0, row))
row += n_rows
return outImage
def cmyk2rgbImage(PILImage, psrc='C:\\Windows\\System32\\spool\\drivers\\color\\CoatedFOGRA39.icc', pdst='C:\\Windows\\System32\\spool\\drivers\\color\\AdobeRGB1998.icc') :
ctxt = lc.cmsCreateContext(None, None)
white = lc.cmsD50_xyY() # Set white point for D50
dst_profile = lc.cmsOpenProfileFromFile(pdst, 'r')
src_profile = lc.cmsOpenProfileFromFile(psrc, 'r')
transform = lc.cmsCreateTransform(src_profile, lc.TYPE_CMYK_8, dst_profile, lc.TYPE_RGB_8,
lc.INTENT_RELATIVE_COLORIMETRIC, lc.cmsFLAGS_NOCACHE)
n_pixels = PILImage.size[0]
in_comps = 4
out_comps = 3
n_rows = 16
cmyk_in = lc.uint8Array(in_comps * n_pixels * n_rows)
rgb_out = lc.uint8Array(out_comps * n_pixels * n_rows)
outImage = Image.new('RGB', PILImage.size, 'white')
in_row = Image.new('CMYK', (PILImage.size[0], n_rows), 'white')
out_row = Image.new('RGB', (PILImage.size[0], n_rows), 'white')
out_b = bytearray(n_pixels * n_rows * out_comps)
row = 0
while row < PILImage.size[1] :
in_row.paste(PILImage, (0, -row))
data_in = in_row.tobytes('raw')
j = in_comps * n_pixels * n_rows
for i in range(j):
cmyk_in[i] = data_in[i]
lc.cmsDoTransform(transform, cmyk_in, rgb_out, n_pixels * n_rows)
for j in rgb_out :
out_b[j] = rgb_out[j]
out_row = Image.frombytes('RGB', in_row.size, bytes(out_b))
outImage.paste(out_row, (0, row))
row += n_rows
return outImage
将小片段导入为lc
从PIL导入图像
def rgb2cmykColor(rgb,psrc='C:\\Windows\\System32\\spool\\drivers\\color\\AdobeRGB1998.icc',pdst='C:\\Windows\\System32\\spool\\drivers\\color\\CoatedFOGRA39.icc'):
ctxt=lc.cmsCreateContext(无,无)
白色=lc.cmsD50_xy()#为D50设置白色点
dst_profile=lc.cmsOpenProfileFromFile(pdst,'r')
src_profile=lc.cmsOpenProfileFromFile(psrc,'r')#cmsCreate_sRGBProfile()
transform=lc.cmsCreateTransform(src_profile,lc.TYPE_RGB_8,dst_profile,lc.TYPE_CMYK_8,
lc.INTENT\U相对比色法,lc.cmsFLAGS\U NOCACHE)
n_像素=1
in_comps=3
out_comps=4
rgb_in=lc.uint8阵列(单位:像素)
cmyk_out=lc.uint8Array(out_comps*n_像素)
对于范围内的i(单位):
rgb_in[i]=rgb[i]
lc.cmsDoTransform(变换、rgb_输入、cmyk_输出、n_像素)
cmyk=元组(cmyk_out[i]表示范围内的i(out_comps*n_像素))
返回cmyk
def cmyk2rgbColor(cmyk,psrc='C:\\Windows\\System32\\spool\\drivers\\color\\CoatedFOGRA39.icc',pdst='C:\\Windows\\System32\\spool\\drivers\\color\\AdobeRGB1998.icc'):
ctxt=lc.cmsCreateContext(无,无)
白色=lc.cmsD50_xy()#为D50设置白色点
dst_profile=lc.cmsOpenProfileFromFile(pdst,'r')
src_profile=lc.cmsOpenProfileFromFile(psrc,'r')#cmsCreate_sRGBProfile()
transform=lc.cmsCreateTransform(src_配置文件、lc.TYPE_CMYK_8、dst_配置文件、lc.TYPE_RGB_8、,
lc.INTENT\U相对比色法,lc.cmsFLAGS\U NOCACHE)
n_像素=1
in_comps=4
out_comps=3
cmyk_in=lc.uint8Array(in_comps*n_像素)
rgb_out=lc.uint8Array(out_comps*n_像素)
对于范围内的i(单位):
cmyk_in[i]=cmyk[i]
lc.cmsDoTransform(变换、cmyk_输入、rgb_输出、n_像素)
rgb=元组(rgb_out[i]表示范围内的i(out_comps*n_像素))
返回rgb
def rgb2cmykImage(PILImage,psrc='C:\\Window