gpt4 book ai didi

python - 使用 python PIL 更改 8 位 .png 图像的调色板

转载 作者:太空狗 更新时间:2023-10-30 02:23:51 25 4
gpt4 key购买 nike

我正在寻找一种将新调色板应用到现有 8 位 .png 图像的快速方法。我怎样才能做到这一点?保存图像时 .png 是否重新编码? (自己的回答:好像是)

我尝试过的(已编辑):

import Image, ImagePalette
output = StringIO.StringIO()
palette = (.....) #long palette of 768 items
im = Image.open('test_palette.png') #8 bit image
im.putpalette(palette)
im.save(output, format='PNG')

对于我的测试图像,保存功能大约需要 65 毫秒。我的想法:没有解码和编码,它可以快很多??

最佳答案

如果您只想更改调色板,那么 PIL 只会妨碍您。幸运的是,当您只对某些数据 block 感兴趣时,PNG 文件格式被设计为易于处理。 PLTE chunk 的格式只是一个 RGB 三元组数组,最后有一个 CRC。要在不读取或写入整个文件的情况下就地更改文件上的调色板:

import struct
from zlib import crc32
import os

# PNG file format signature
pngsig = '\x89PNG\r\n\x1a\n'

def swap_palette(filename):
# open in read+write mode
with open(filename, 'r+b') as f:
f.seek(0)
# verify that we have a PNG file
if f.read(len(pngsig)) != pngsig:
raise RuntimeError('not a png file!')

while True:
chunkstr = f.read(8)
if len(chunkstr) != 8:
# end of file
break

# decode the chunk header
length, chtype = struct.unpack('>L4s', chunkstr)
# we only care about palette chunks
if chtype == 'PLTE':
curpos = f.tell()
paldata = f.read(length)
# change the 3rd palette entry to cyan
paldata = paldata[:6] + '\x00\xff\xde' + paldata[9:]

# go back and write the modified palette in-place
f.seek(curpos)
f.write(paldata)
f.write(struct.pack('>L', crc32(chtype+paldata)&0xffffffff))
else:
# skip over non-palette chunks
f.seek(length+4, os.SEEK_CUR)

if __name__ == '__main__':
import shutil
shutil.copyfile('redghost.png', 'blueghost.png')
swap_palette('blueghost.png')

此代码将 redghost.png 复制到 blueghost.png 并就地修改 blueghost.png 的调色板。

red ghost -> blue ghost

关于python - 使用 python PIL 更改 8 位 .png 图像的调色板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1158736/

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