我想阅读,操作,然后保存一个png图像,同时保留它的原始info属性,主要是gamma。我使用的是Pillow版本9.0.1
从SO提到的代码可以这样做:
from PIL import Image
img = Image.open("sample.png") # Sample image provided below code block
info = img.info
img.save("output.png", **info)但是info不再继续;由于丢失了gamma信息,这些图像不再像以前那样了,并且通过测试进一步证明了这一点:
# Test
output_info = Image.open("output.png").info
print(info) # {'gamma': 2147.48365}
print(output_info) # {}
print(output_info == info) # False, should be True问题:为什么PIL的Image.save不写gamma
它并不是gamma特有的,没有其他块可以像chromaticity和text那样编写。
sample.png与output.png相比(使用gAMA感知的查看器查看,比如铬)。

发布于 2022-03-25 12:20:59
看来我的期望是错的。PIL的PNG文件写入器不支持gamma关键字参数,因此它被静默忽略。正如所记录的那样:
save()方法支持以下选项:
Image.save忽略不可识别的关键字参数:关键字选项可用于向作者提供附加说明。如果一个作家不承认一个选项,它就会被默默地忽略。
发布于 2022-03-24 10:25:55
这里有一种方法,不使用任何外部的东西来做你要求的事情。它插入gAMA块如下:
注意事项:PNG规范规定签名必须先来,然后是IHDR块。它还规定,gAMA必须位于IDAT之前,因此,我的代码没有理由创建无效的PNG,除非:
#!/usr/bin/env python3
import zlib
import struct
from io import BytesIO
from PIL import Image
def savePNGwithGamma(im, filename, gamma):
"""Save the image as PNG with specified gamma"""
# Encode as PNG into memory buffer
buffer = BytesIO()
im.save(buffer, 'PNG')
# Seek back to start of in-memory PNG
buffer.seek(0)
# Open output file in binary mode
with open(filename, 'wb') as fd:
# Read 8-byte PNG signature from memory and write to on-disk PNG
signature = buffer.read(8)
fd.write(signature)
# Read 25-byte PNG IHDR chunk from memory and write to on-disk PNG
IHDR = buffer.read(25)
fd.write(IHDR)
# Create our lovely new gAMA chunk - https://www.w3.org/TR/2003/REC-PNG-20031110/#11gAMA
# Network byte ordering, scale factor of 100000
gAMA = b'gAMA' + struct.pack('!I',int(gamma*100000))
# 4-byte length, gAMA chunk, 4-byte CRC
gAMA = struct.pack('!I', 4) + gAMA + struct.pack('!I', zlib.crc32(gAMA))
# Insert into on-disk PNG after IHDR and before anything else such as PLTE, IDAT, IEND
fd.write(gAMA)
# Write remainder of PNG from memory to disk
fd.write(buffer.read())
################################################################################
# main
################################################################################
# Load sample image
im = Image.open('sample.png')
# Save with desired gamma
savePNGwithGamma(im, 'result.png', 2.2)https://stackoverflow.com/questions/71543170
复制相似问题