【问题标题】:Convert JPG from AdobeRGB to sRGB using PIL?使用 PIL 将 JPG 从 Adob​​eRGB 转换为 sRGB?
【发布时间】:2012-06-14 20:42:24
【问题描述】:

如何检测 JPG 是否为 Adob​​eRGB,以及是否在 python 中将其转换为 sRGB JPG。

如果这在 PIL 中是可能的,那就太好了。谢谢。

【问题讨论】:

  • 查看问题Converting JPEG colorspace (Adobe RGB to sRGB) on Linux -- 抱歉上次链接搞砸了。
  • 您是否仍然有兴趣获得这个问题的更好答案?
  • 当然。你找到更好的办法了吗?
  • 不完全是,但我可以通过使其更具体来改进我的答案——如果这是你正在寻找的,因为到目前为止你还没有接受答案。跨度>

标签: python image-processing python-imaging-library jpeg color-profile


【解决方案1】:

我遇到了同样的问题,我测试了所有答案并在最终图像中得到错误的颜色。 @DrMeers 我尝试过的所有矩阵都给出了错误的红色和黑色结果,所以这是我的解决方案:

我发现的唯一方法是从图像中读取配置文件并使用 ImageCms 进行转换。

from PIL import Image
from PIL import ImageCms
import tempfile

def is_adobe_rgb(img):
    return 'Adobe RGB' in img.info.get('icc_profile', '')
def adobe_to_srgb(img):
    icc = tempfile.mkstemp(suffix='.icc')[1]
    with open(icc, 'w') as f:
        f.write(img.info.get('icc_profile'))
    srgb = ImageCms.createProfile('sRGB')
    img = ImageCms.profileToProfile(img, icc, srgb)
    return img

img = Image.open('testimage.jpg')
if is_adobe_rgb(img):
    img =  adobe_to_srgb(img)
# then do all u want with image. crop, rotate, save etc.

我认为这种方法可以用于任何颜色配置文件,但未经测试。

【讨论】:

    【解决方案2】:

    感谢规范链接 martineau,我已将一些工作 PIL 代码与检测 Image 中是否存在 Adob​​e RGB ICC 配置文件并将色彩空间转换为 sRGB 的函数放在一起。

    adobe_to_xyz = (
        0.57667, 0.18556, 0.18823, 0,
        0.29734, 0.62736, 0.07529, 0,
        0.02703, 0.07069, 0.99134, 0,
    ) # http://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf                                
    
    xyz_to_srgb = (
        3.2406, -1.5372, -0.4986, 0,
        -0.9689, 1.8758, 0.0415, 0,
        0.0557, -0.2040, 1.0570, 0,
    ) # http://en.wikipedia.org/wiki/SRGB                                                     
    
    def adobe_to_srgb(image):
        return image.convert('RGB', adobe_to_xyz).convert('RGB', xyz_to_srgb)
    
    def is_adobe_rgb(image):
        return 'Adobe RGB' in image.info.get('icc_profile', '')
    
    # alternative solution if happy to retain profile dependency:                             
    # http://stackoverflow.com/a/14537273/284164                                              
    # icc_profile = image.info.get("icc_profile")                                             
    # image.save(destination, "JPEG", icc_profile=icc_profile)
    

    (我用这些创建了Djangoeasy-thumbnails处理器函数):

    def preserve_adobe_rgb(image, **kwargs):
        if is_adobe_rgb(image):
            return adobe_to_srgb(image)
        return image
    

    【讨论】:

    • 是的,您可以组合矩阵并在单个 convert 操作中完成。
    【解决方案3】:

    要自行编程,您可以将 Adob​​eRGB 颜色空间中的像素转换为 CIE XYZ,然后再将其转换为 sRGB。 PIL image 对象有一个名为 convert() 的方法,能够对图像中的所有像素应用一般矩阵变换(请参阅 PIL Image 模块的在线文档中关于 Image.convert() 的部分——注意示例显示从 RGB 到 XYZ 所需的矩阵值)。

    AdobeRGB1998 .pdf spec 中的第 4.3.4 节显示了将 XYZ 转换为 RGB 的矩阵。

    我不确定如何检测 JPG 图像的色彩空间。我记得读过一些关于附加到文件末尾的 ICC xml 配置文件(以及当有多个文件时出现的问题),但我不能保证它的有效性。 JPEG file format 上的维基百科文章说配置文件是嵌入的。

    【讨论】:

    • @miki725:如果您采用这种方法,请注意这两个矩阵变换可以组合起来,这样可以一步完成转换(一个 im.convert() 调用)。有关将矩阵相乘的更多信息,请参阅此 Wikipedia article
    猜你喜欢
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    • 2012-05-03
    • 2016-10-17
    • 1970-01-01
    • 2016-06-27
    • 1970-01-01
    • 2021-04-21
    相关资源
    最近更新 更多