如何创建带有 alpha 通道的基于调色板的 PNG?
How to create a palette-based PNG with alpha channel?
我有一个 2D NumPy 数组,其值从 0
到 6
(对应于图像分割 类),我想将它变成颜色索引的 PNG使用 Pillow Image.putpalette()
的图像(使用版本 8.0.1
)。调色板应包含一个 alpha 通道。根据官方文档,这应该是可能的:
The palette sequence must contain either 768 integer values, or 1024 integer values if alpha is included. Each group of values represents the red, green, blue (and alpha if included) values for the corresponding pixel index. Instead of an integer sequence, you can use an 8-bit string.
到目前为止,我只在没有 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())
上面的效果很好。
但是,如果我尝试包含 alpha 通道(据我所知,我必须将其附加到末尾),我将一事无成:
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
也无济于事...
有人能指出我正确的方向吗?谢谢!
您需要在 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
----------------------------------------
我有一个 2D NumPy 数组,其值从 0
到 6
(对应于图像分割 类),我想将它变成颜色索引的 PNG使用 Pillow Image.putpalette()
的图像(使用版本 8.0.1
)。调色板应包含一个 alpha 通道。根据官方文档,这应该是可能的:
The palette sequence must contain either 768 integer values, or 1024 integer values if alpha is included. Each group of values represents the red, green, blue (and alpha if included) values for the corresponding pixel index. Instead of an integer sequence, you can use an 8-bit string.
到目前为止,我只在没有 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())
上面的效果很好。
但是,如果我尝试包含 alpha 通道(据我所知,我必须将其附加到末尾),我将一事无成:
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
也无济于事...
有人能指出我正确的方向吗?谢谢!
您需要在 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
----------------------------------------