支持SRGB的图像在Pillow中调整大小

时间:2015-07-08 18:31:58

标签: python pillow srgb

Pillow的基本Image.resize功能似乎没有任何SRGB感知过滤选项。有没有办法在Pillow中进行SRGB感知调整大小?

我可以通过将图像转换为浮动来手动完成并应用SRGB转换自己...但我希望有内置的方式。

3 个答案:

答案 0 :(得分:3)

我最终使用以下例程实现了sRGB感知调整大小。它需要一个8位RGB图像和一个目标大小和重采样过滤器。

from PIL import Image
import numpy as np

def SRGBResize(im, size, filter):
    # Convert to numpy array of float
    arr = np.array(im, dtype=np.float32) / 255.0
    # Convert sRGB -> linear
    arr = np.where(arr <= 0.04045, arr/12.92, ((arr+0.055)/1.055)**2.4)
    # Resize using PIL
    arrOut = np.zeros((size[1], size[0], arr.shape[2]))
    for i in range(arr.shape[2]):
        chan = Image.fromarray(arr[:,:,i])
        chan = chan.resize(size, filter)
        arrOut[:,:,i] = np.array(chan)
    # Convert linear -> sRGB
    arrOut = np.where(arrOut <= 0.0031308, 12.92*arrOut, 1.055*arrOut**(1.0/2.4) - 0.055)
    # Convert to 8-bit
    arrOut = np.uint8(np.rint(arrOut * 255.0))
    # Convert back to PIL
    return Image.fromarray(arrOut)

答案 1 :(得分:2)

经过大量的阅读和反复试验后,我偶然发现了一个很好的解决方案。它假设一个sRGB图像,将其转换为线性颜色空间以进行调整大小,然后转换回sRGB。

即使图像是线性形式,也会使用每像素8位的颜色深度。这导致较暗区域的变化损失。从this issue post读取,似乎无法使用Pillow转换到更高的深度。

from PIL import Image
from PIL.ImageCms import profileToProfile

SRGB_PROFILE = 'sRGB.icc'
LINEARIZED_PROFILE = 'linearized-sRGB.icc'

im = Image.open(IN_PATH)
im = profileToProfile(im, SRGB_PROFILE, LINEARIZED_PROFILE)
im = im.resize((WIDTH, HEIGHT), Image.ANTIALIAS)
im = profileToProfile(im, LINEARIZED_PROFILE, SRGB_PROFILE)

im.save(OUT_PATH)

你需要一个线性化的ICC颜色配置文件,因为Pillow / lcms不能没有。你可以从this issue post获得一个,作者在文件中提到“没有版权,可以自由使用”。您还需要一个sRGB配置文件,可以从您的操作系统或在线轻松获取。

大部分处理时间用于计算sRGB的转换并再次返回。如果您要进行大量的这些操作,您可以存储这些转换以重复使用它们,如下所示:

from PIL.ImageCms import buildTransform, applyTransform

SRGB_TO_LINEARIZED = buildTransform(SRGB_PROFILE, LINEARIZED_PROFILE, 'RGB', 'RGB')
LINEARIZED_TO_SRGB = buildTransform(LINEARIZED_PROFILE, SRGB_PROFILE, 'RGB', 'RGB')

im = applyTransform(im, SRGB_TO_LINEARIZED)
im = im.resize((WIDTH, HEIGHT), Image.ANTIALIAS)
im = applyTransform(im, LINEARIZED_TO_SRGB)

我希望这会有所帮助,我有兴趣听听是否有人对解决8位色彩空间问题有任何想法。

答案 2 :(得分:1)

99%的图像调整大小实现不会使sRGB正确(不幸的是,这是图像资料的99.9%),而那些通常会默认执行此操作并允许您选择退出gamma de /编码

[见解模式,小心阅读]

IOW,如果没有选项,您可能需要自己添加代码 - 或者只使用pamscale。如果图书馆没有获得sRGB权利,那么无论如何都会有其他缺陷。

[见解模式]

您可以按照

中的讨论对自己进行编码

http://www.imagemagick.org/discourse-server/viewtopic.php?t=15955

但从快速浏览一下,枕头似乎无法做到这一点。