【问题标题】:Does PIL image.convert("RGB") convert images to sRGB or AdobeRGB?PIL image.convert("RGB") 是否将图像转换为 sRGB 或 Adob​​eRGB?
【发布时间】:2018-05-31 10:30:09
【问题描述】:

我想在 Python 中使用 PIL 将图像从各种模式(如 RGBa、CMYK 等)批量转换为 sRGB。

但是,我不确定,也无法在任何地方找到它

image.convert("RGB") 

将图像转换为 sRGB 或 Adob​​e RGB。我的直觉说它会转换为 sRGB。

如果它转换为 sRGB 并且我将 Adob​​e RGB 图像传递给convert 函数,它会成功转换为 sRGB 吗?

【问题讨论】:

    标签: python image python-imaging-library rgb


    【解决方案1】:

    默认情况下,PIL 与颜色空间无关(如 sRGB 和 Adob​​e RGB)。

    您可能知道,RGB 只是红色、绿色和蓝色的三个 8 位值。 CMYK 是四个 8 位值。当您使用Image.convert('RGB') 时,它只是将每个像素转换为三个 8 位值。因此,它从根本上改变了图像的表示和存储方式的模式

    另一方面,

    sRGB 和 Adob​​e RGB 只是 RGB 颜色空间。基本上,这些是关于如何在显示器、打印机或任何其他物理输出设备上呈现这三个值的规则。例如,这些规则可以通过 Photoshop 等软件以 ICC 配置文件的形式添加到 JPEG 文件中。但是当您只使用Image.save 时,PIL 通常不会附加任何 ICC 配置文件。

    为了检查您的图像是否嵌入 ICC 配置文件,您可以在字典 image.info 中查找密钥 'icc_profile',例如 image.info.get('icc_profile', None)

    为了使用 PIL 保存 JPEG 图像并保留 ICC 配置文件,您可以使用以下内容:

    img.save('image.jpg',
             format = 'JPEG',
             quality = 100,
             icc_profile = img.info.get('icc_profile',''))
    

    要将任何 RGB JPEG 图像从其颜色空间转换为 sRGB,您可以使用此函数:

    import io
    from PIL import Image
    from PIL import ImageCms
    
    def convert_to_srgb(img):
        '''Convert PIL image to sRGB color space (if possible)'''
        icc = img.info.get('icc_profile', '')
        if icc:
            io_handle = io.BytesIO(icc)     # virtual file
            src_profile = ImageCms.ImageCmsProfile(io_handle)
            dst_profile = ImageCms.createProfile('sRGB')
            img = ImageCms.profileToProfile(img, src_profile, dst_profile)
        return img
    

    因此,您转换为单一 RGB 颜色空间的代码可能如下所示:

    img = Image.open('image_AdobeRGB.jpg')
    img_conv = convert_to_srgb(img)
    if img.info.get('icc_profile', '') != img_conv.info.get('icc_profile', ''):
        # ICC profile was changed -> save converted file
        img_conv.save('image_sRGB.jpg',
                      format = 'JPEG',
                      quality = 100,
                      icc_profile = img_conv.info.get('icc_profile',''))
    

    注意:您可能希望使用略低于 100 的质量。

    示例输入(Adobe RGB JPEG):

    示例输出(sRGB JPEG):

    【讨论】:

    • 这里提到的从 sRGB 转换为 Adob​​e RGB 需要应用的矩阵变换怎么样:stackoverflow.com/questions/40017741/…
    • @SabihHasan,在我的示例中,此类数学是由ImageCms.profileToProfile 在内部完成的。当您想要使两个具有不同色彩空间的图像在屏幕上看起来相同(或非常相似)时,这是需要的。就像我的样本输入和样本输出一样。由于颜色空间不同,底层 RGB 字节需要不同才能实现。所以这个数学只是计算RGB字节需要多少才能使图片在不同的色彩空间中看起来相同。 (相反,如果两个图像具有相同的 RGB 字节,但具有不同的色彩空间,它们在屏幕上看起来会有所不同。)
    • 此解决方案似乎也适用于 CMYK 图像,只要您将选项 renderingIntent=, outputMode='RGB' 添加到 profileToProfile
    猜你喜欢
    • 1970-01-01
    • 2017-02-22
    • 2016-06-27
    • 2016-10-17
    • 2018-08-15
    • 2020-01-22
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    相关资源
    最近更新 更多