Python 为什么打开并显示此图像时颜色会完全改变?如何将ICC配置文件添加到图像?

Python 为什么打开并显示此图像时颜色会完全改变?如何将ICC配置文件添加到图像?,python,python-3.x,python-imaging-library,color-profile,Python,Python 3.x,Python Imaging Library,Color Profile,这是原始图像: 这是我打开并用枕头展示后的图像: 原始图像是JPEG,但我尝试将格式更改为TIFF、PSD,但没有任何效果。我试过将图像转换为RGB、RGBA、CMYK,但看不到任何改进 如果我只是简单地截图,并打开它在枕头,颜色是保留下来的 然后我想我可能不需要枕头,我可以使用另一个库,并尝试OpenCV,但同样的事情发生了!结果与上图相同 正如@HansHirse在我上一个问题的评论中所建议的那样,这篇帖子让我意识到,当我刚刚保存图像时,颜色会被保留下来。(尽管只是在不使用ICC配置文件

这是原始图像:

这是我打开并用枕头展示后的图像:

原始图像是JPEG,但我尝试将格式更改为TIFF、PSD,但没有任何效果。我试过将图像转换为RGB、RGBA、CMYK,但看不到任何改进

如果我只是简单地截图,并打开它在枕头,颜色是保留下来的

然后我想我可能不需要枕头,我可以使用另一个库,并尝试OpenCV,但同样的事情发生了!结果与上图相同

正如@HansHirse在我上一个问题的评论中所建议的那样,这篇帖子让我意识到,当我刚刚保存图像时,颜色会被保留下来。(尽管只是在不使用ICC配置文件的情况下打开并保存会生成准确的图像。)

从PIL导入图像
i=Image.open(“/Users/shashwataryal/Downloads/Tom Ford Rodeo.jpeg”)
##打开后立即保存图像时,颜色会保留下来。
i、 保存(“/Users/shashwataryal/Downloads/1.jpeg”)
##但是,如果我创建一个新的图像并粘贴我的图像,我也会遇到同样的问题。
##图像非常饱和。(不像@HansHirse在我上一篇文章中提出的问题那样乏味)
图层=图像。新建('RGB',i.size,“#FAF8”)
layer.show()
图层粘贴(一)
layer.show()
layer.save('/Users/shashwataryal/Downloads/1.jpeg',icc_profile=i.info.get('icc_profile'))
layer.save('/Users/shashwataryal/Downloads/2.jpeg',icc_profile=i.info.get('icc_profile'))
我正在尝试将该图像添加到一个新的空白枕头图像中,可能还会添加其他图像。我不知道如何将ICC配置文件添加到新图像中。如果我将它们粘贴到枕头中创建的新图像上,会影响其他图像吗

我的上一个问题被标记为以下问题的副本:

虽然这个问题与此类似,但它只是处理打开后立即保存图像的问题,我在打开后立即保存图像没有问题。我的问题是将其粘贴到一块大的空白画布上后再保存。

您需要枕头模块:

ImageCms
模块提供颜色配置文件管理支持[…]

对于下面的演示代码,我使用了来自的具有不同嵌入式ICC配置文件的示例图像

从matplotlib导入pyplot作为plt
从PIL导入图像,图像CMS
从io导入字节io
#测试图像的干涉
infices=['sRGB','AdobeRGB','ColorMatch','ProPhoto','WideRGB']
#初始化输出可视化
plt.图(1,figsize=(19,9))
#迭代内插
对于i_中缀,枚举中缀(中缀,开始=1):
#读取图像
image=image.open('Momiji-{}-yes.jpg'.格式(中缀))
#提取原始ICC配置文件
orig_icc=ImageCms.ImageCmsProfile(BytesIO(image.info.get('icc_profile'))
desc=ImageCms.getProfileDescription(原始icc)
#使用原始ICC配置文件打印图像
plt.子地块(2,len(infices),i_infix),plt.imshow(图像)
plt.title('原始ICC配置文件:{}'。格式(描述))
#创建sRGB ICC配置文件并将图像转换为sRGB
srgb\u icc=ImageCms.createProfile('srgb'))
image=ImageCms.profileToProfile(图像、原始icc、srgb\U icc)
#使用sRGB ICC配置文件打印转换后的图像
plt.子地块(2,len(infices),len(infices)+i_infix),plt.imshow(图像)
产品名称(“sRGB ICC配置文件”)
plt.tight_布局(),plt.show()
代码提取每个样本图像的ICC配置文件,并将其存储为对象。使用,您可以创建一个内置的sRGB ICC配置文件,我使用该配置文件来校正所有输入图像,方法是:

正如您所看到的,输入图像有非常明显的颜色差异,而输出图像非常相似(我没有检查像素是否相等)

如果您想保留特定输入图像的ICC配置文件,只需在开始时保存该文件,然后使用该ICC配置文件更正所有输入图像。例如,这是将所有输入图像转换为“ProPhoto RGB”ICC配置文件的输出:

因此,您需要打开图像,提取ICC配置文件,将图像粘贴到新的空白画布上,并将生成的图像转换为保存的ICC配置文件。如果您有来自不同来源的图像,因此可能有不同的嵌入式ICC配置文件,您需要决定要做什么:(1)纠正所有输入图像,如上图所示,合并可能的颜色差异或(2)实际转换输入图像的颜色,使其具有相同的外观,但使用国际商会的最终结果简介。后者本身就是一个话题

----------------------------------------
系统信息
----------------------------------------
平台:Windows-10-10.0.19041-SP0
Python:3.9.1
PyCharm:2021.1.1
Matplotlib:3.4.2
枕头:8.2.0
----------------------------------------

我需要更改line
image=ImageCms.profileToProfile(image、orig\u icc、srgb\u icc)
并添加输出模式和渲染意图参数,以便开始工作
img=ImageCms.profileToProfile(img,src_profile,dst_profile,renderingIntent=0,outputMode='RGB')
虽然这确实解决了我提出的问题,但事实证明这是XY问题的另一个例子。我只是将我在枕头中创建的新图像的配置文件更改为CMYK
canvas=Image.new('CMYK',(canvas\u-width\u-px,canvas\u-height\u-px),0)
,也可以帮助有类似问题的人