10

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

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

image.convert("RGB") 

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

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

4

1 回答 1

18

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

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

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

为了检查您的图像是否嵌入了 ICC 配置文件,您可以像这样'icc_profile'在字典中查找键。 image.infoimage.info.get('icc_profile', None)

为了保存 JPEG 图像,使用 PIL 保留 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):

Adobe RGB JPG

示例输出(sRGB JPEG):

sRGB JPG

于 2018-05-31T11:59:53.207 回答