如何创建带有Alpha通道的调色板PNG?

3
我有一个包含从06的值(对应于图像分割类)的二维NumPy数组,并且我想使用Pillow(版本为8.0.1)中的Image.putpalette()将其转换为带有颜色索引的PNG图像。颜色调色板应该包含一个alpha通道。根据官方文档,这应该是可能的:
“调色板序列必须包含768个整数值或1024个整数值(如果包括alpha)。每组值表示相应像素索引的红色、绿色、蓝色(如果包括alpha,则还有alpha)值。您可以使用8位字符串而不是整数序列。”
迄今为止,我只成功了没有alpha通道的情况:
from PIL import Image
import matplotlib.cm as cm
import numpy as np

# test data
np.random.seed(42)
mask = np.random.randint(low=0, high=6, size=(32, 32))

# color palette - random colors for testing
colormap = np.zeros((256, 3))
colormap[:7, :] = cm.jet(np.linspace(0, 1, 7))[:, :3]

img = Image.fromarray(mask.astype(np.uint8))
img = img.convert("P")
img.putpalette((colormap * 255).astype(np.uint8).flatten())

上述方法效果很好。

然而,如果我试图包含透明通道(据我所知,必须附加在末尾),我就无从下手:

img = Image.fromarray(corrected_mask.astype(np.uint8))
img = img.convert("P")
img.putpalette(np.append((colormap[:, :] * 255).astype(np.uint8).flatten(), np.ones(256, dtype=np.uint8) * 255))

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-65-6a955d432bbc> in <module>
      1 img = Image.fromarray(corrected_mask.astype(np.uint8))
      2 img = img.convert("P")
----> 3 img.putpalette(np.append((colormap[:, :] * 255).astype(np.uint8).flatten(), np.ones(256, dtype=np.uint8) * 255))

~/miniconda3/envs/tf2_py38/lib/python3.8/site-packages/PIL/Image.py in putpalette(self, data, rawmode)
   1697         self.palette = palette
   1698         self.palette.mode = "RGB"
-> 1699         self.load()  # install new palette
   1700 
   1701     def putpixel(self, xy, value):

~/miniconda3/envs/tf2_py38/lib/python3.8/site-packages/PIL/Image.py in load(self)
    816         if self.im and self.palette and self.palette.dirty:
    817             # realize palette
--> 818             self.im.putpalette(*self.palette.getdata())
    819             self.palette.dirty = 0
    820             self.palette.mode = "RGB"

ValueError: invalid palette size

试图将模式设置为 PA 也没有任何作用...

能否有人指点我正确的方向?谢谢!

1个回答

4

在使用putpalette时,需要显式设置rawmode='RGBA',因为它的默认值为'RGB'

from PIL import Image
import matplotlib.cm as cm
import numpy as np

# test data
np.random.seed(42)
mask = np.random.randint(low=0, high=6, size=(32, 32))

# color palette - random colors for testing
colormap = np.zeros((256, 4))
colormap[:7, :3] = cm.jet(np.linspace(0, 1, 7))[:, :3]
colormap[:7, 3] = np.linspace(0, 1, 7)

img = Image.fromarray(mask.astype(np.uint8))
img = img.convert('P')
img.putpalette((colormap * 255).astype(np.uint8).flatten(), rawmode='RGBA')

img.save('image.png')

这会生成一个类似于以下的图像,其中每种颜色都具有特定的 alpha 值:

输出

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
Matplotlib:    3.3.4
NumPy:         1.20.1
Pillow:        8.1.0
----------------------------------------

非常感谢,这个方法可行!只是为了完整起见:我需要将 pillow 从 8.0.1 升级到 >=8.1!在 8.0.1 中,rawmode='RGBA' 无法被识别:ValueError: unrecognized raw mode - Ulrich Noebauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接