Я хочу читать, манипулировать, а затем сохранять изображение 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's Image.save
нет пишет gamma
?
Это не относится к gamma
, никакой другой фрагмент не записывается так, как chromaticity
и text
.
sample.png
по сравнению с output.png
(при просмотре с помощью средства просмотра с поддержкой gAMA, например хрома)
@MarkSetchell Я не хочу спорить с байтами и иметь дело со стандартами. Параметра Image.save
pnginfo
должно быть достаточно, но это не так. И я спрашиваю, почему это так. Я думаю, что мог иметь в виду, что мне нужно решение для встраивания информации о гамме, которого у меня нет.
Возможно, в таком случае поднимите вопрос в репозитории PIL Github... и добавьте сюда ссылку, чтобы другие люди могли ее найти.
@MarkSetchell Подойдет. Просто подумал, что у этого случая была другая задокументированная семантика, о которой я просто не знал. Спасибо.
Вот способ сделать то, что вы просите, без использования чего-либо внешнего. Он вставляет блок ГАМА следующим образом:
Примечание: Спецификация PNG предусматривает, что сначала должна идти подпись, а затем блок ИХДР. Он также предусматривает, что ГАМА должен предшествовать ИДАТ, поэтому нет причин, по которым мой код должен создавать недопустимый PNG, если только:
ПИЛ внезапно начинает генерировать фрагменты ГАМА, что привело бы к множеству таких фрагментов и было бы незаконным, но мы делаем это только потому, что PIL не записывает фрагменты ГАМА, или
предоставлено необоснованное значение гаммы, или
некоторый аспект записи в 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)
Я действительно ценю ответ с большими усилиями, но это не то, что я ищу. Я прочитал Ваш ответ 2 года назад, где вы упомянули «Я не знаю, почему Pillow не может сохранить информацию о вашей гамме», и это то, что я хочу знать. Прошу прощения, возможно мой вопрос был не ясен.
Похоже, мои ожидания не оправдались. Средство записи файлов PNG PIL не поддерживает аргумент ключевого слова gamma
, поэтому он молча игнорируется. Точно так, как задокументировано:
gamma
после строки в кавычках под Документация по формату PNG PIL:The save() method supports the following options:
Keyword options can be used to provide additional instructions to the writer. If a writer doesn’t recognise an option, it is silently ignored.
PngInfo
в PIL? И какие возражения против этого, пожалуйста?