8

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

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

4

3 回答 3

6

我最终使用以下例程实现了 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).clip(0.0, 1.0)
    # 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)
于 2015-07-23T20:50:12.037 回答
2

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

有一个轻微的缺点是,即使图像处于线性形式,也使用每像素 8 位的颜色深度。这导致较暗区域的方差损失。从这个问题帖子中阅读,不幸的是,似乎没有办法使用 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 就无法做到。你可以从这个问题帖子中得到一个,作者在文件中提到“无版权,自由使用”。您还需要一个 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 位色彩空间问题有任何想法。

于 2017-10-06T20:39:32.703 回答
1

99% 的图像调整大小实现不会正确地获得 sRGB(不幸的是,这是 99.9% 的图像材料),而通常这样做的人默认情况下会正确执行,并为您提供选择退出伽马解码/编码的选项。

【观点模式开启,请谨慎阅读】

IOW,如果没有选项,您可能必须自己添加代码 - 或者只使用 pamscale。如果一个库没有获得正确的 sRGB,它无论如何都会有其他缺陷。

[自以为是模式关闭]

您可以按照中的讨论对自己进行解码/编码

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

但乍一看,枕头似乎无法做到这一点。

于 2015-07-11T16:04:13.773 回答