gpt4 book ai didi

python-3.x - 如何使用 Python 和 Pillow 将此索引 PNG 转换为灰度并保持透明度?

转载 作者:行者123 更新时间:2023-12-02 20:20:48 24 4
gpt4 key购买 nike

我正在尝试使用 Python/Pillow 将图像转换为灰度。我在大多数图像中都没有遇到困难,但是,在使用不同图像进行测试时,我发现了 BeeWare 项目中的这个 Logo ,我知道它已使用某些图像编辑器进行了进一步编辑,并使用 ImageOptim 进行了重新压缩。

enter image description here

图像具有某种透明度(在蜜蜂周围的整个白色区域),但黑色会变得困惑。这是代码:

#/usr/bin/env python3

import os
from PIL import Image, ImageFile

src_path = os.path.expanduser("~/Desktop/prob.png")
img = Image.open(src_path)
folder, filename = os.path.split(src_path)
temp_file_path = os.path.join(folder + "/~temp~" + filename)


if 'transparency' in img.info:
transparency = img.info['transparency']
else:
transparency = None

if img.mode == "P":
img = img.convert("LA").convert("P")

try:
img.save(temp_file_path, optimize=True, format="PNG", transparency=transparency)
except IOError:
ImageFile.MAXBLOCK = img.size[0] * img.size[1]
img.save(temp_file_path, optimize=True, format="PNG", transparency=transparency)

我也尝试过这个:

png_info = img.info

if img.mode == "P":
img = img.convert("LA").convert("P")

try:
img.save(temp_file_path, optimize=True, format="PNG", **png_info)
except IOError:
ImageFile.MAXBLOCK = img.size[0] * img.size[1]
img.save(temp_file_path, optimize=True, format="PNG", **png_info)

使用任何一种方法,图像中的所有黑色都会变得透明。

enter image description here

我试图了解我在这里缺少什么,或者这是否是 Pillow 中的一些错误或限制。仔细研究一下图像调色板,我会说透明度实际上分配给调色板中的黑色。例如,如果我将其转换为 RGBA 模式,则外部会变成黑色。因此必须有其他东西使外部区域透明。

有什么建议吗?

最佳答案

Digging a little through the image palette, I would say that transparency is in fact assigned to the black color in the palette.

pngcheck告诉我事实并非如此:

...
chunk PLTE at offset 0x00025, length 48: 16 palette entries
chunk tRNS at offset 0x00061, length 1: 1 transparency entry

每种实际颜色在PLTE中都有一个索引,包括黑色,并且还有一个被指定为“透明”的附加条目。黑色环境可能是之前转换之一的产物,其中 alpha=0 被转换为 RGBA (0,0,0,0)。

似乎 Pillow 立即转换为 Lab(“L”和“LA”)无法处理索引颜色转换。
您可以通过首先将图像转换为 RGBA,然后使用 the documentation 中的 Lab 转换公式将 RGBA 的每个像素四元组转换为灰度来解决此问题。 ,然后将其转换回调色板:

for i in range(img.size[0]): # for every pixel:
for j in range(img.size[1]):
g = (pixels[i,j][0]*299 + pixels[i,j][1]*587 + pixels[i,j][2]*114)//1000
pixels[i,j] = (g,g,g,pixels[i,j][3])

但后来我意识到,由于您从调色板图像开始并希望再次以调色板结束,仅转换调色板要容易得多......

#/usr/bin/env python3

from PIL import Image, ImageFile

img = Image.open('bee.png')

palette = img.getpalette()
for i in range(len(palette)//3):
gray = (palette[3*i]*299 + palette[3*i+1]*587 + palette[3*i+2]*114)//1000
palette[3*i:3*i+3] = [gray,gray,gray]

img.putpalette(palette)
img.save('bee2a.png', optimize=True, format="PNG")

print ('done')

(硬编码以假设您的输入图像确实是索引文件。如果您想确定,请添加检查。)

结果,包含在注释 block 内,以便您可以看到透明度:

a gray bee

关于python-3.x - 如何使用 Python 和 Pillow 将此索引 PNG 转换为灰度并保持透明度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51445513/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com