首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >枕头保存方法忽略信息参数

枕头保存方法忽略信息参数
EN

Stack Overflow用户
提问于 2022-03-20 00:38:03
回答 2查看 254关注 0票数 0

我想阅读,操作,然后保存一个png图像,同时保留它的原始info属性,主要是gamma。我使用的是Pillow版本9.0.1

从SO提到的代码可以这样做:

代码语言:javascript
复制
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信息,这些图像不再像以前那样了,并且通过测试进一步证明了这一点:

代码语言:javascript
复制
# 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特有的,没有其他块可以像chromaticitytext那样编写。

sample.pngoutput.png相比(使用gAMA感知的查看器查看,比如铬)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-03-25 12:20:59

看来我的期望是错的。PIL的PNG文件写入器不支持gamma关键字参数,因此它被静默忽略。正如所记录的那样:

save()方法支持以下选项:

关键字选项可用于向作者提供附加说明。如果一个作家不承认一个选项,它就会被默默地忽略。

票数 0
EN

Stack Overflow用户

发布于 2022-03-24 10:25:55

这里有一种方法,不使用任何外部的东西来做你要求的事情。它插入gAMA块如下:

  • 它使PIL将图像编码为“内存中”PNG。
  • 它以二进制模式打开磁盘上的输出文件。
  • 然后,它获取由PIL创建的8字节PNG签名,并将其写入磁盘。
  • 同样,由PIL创建的25字节IHDR
  • 然后,它使用您的值创建一个gAMA块,在长度前面加上一个CRC并写入磁盘。
  • 然后,它将PIL生成的映像的其余部分复制到磁盘。

注意事项:PNG规范规定签名必须先来,然后是IHDR块。它还规定,gAMA必须位于IDAT之前,因此,我的代码没有理由创建无效的PNG,除非:

  • PIL 突然开始生成gAMA块,这会导致多个这样的块,并且是非法的,但我们这样做只是因为PIL不编写gAMA块,或者
  • 提供不合理的伽马值,或
  • 写入磁盘上PNG的某些方面由于磁盘满或其他I/O错误而失败。
代码语言:javascript
复制
#!/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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71543170

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档