Как улучшить качество функции ‘image.save()’?

#python #image #python-imaging-library

#python #изображение #python-imaging-library

Вопрос:

Я сохранил изображение в буфер обмена, и когда я прочитал информацию об изображении из буфера обмена и сохранил его локально, качество изображения изменилось. Как я могу сохранить ее, чтобы сохранить исходное высокое качество?

 from PIL import ImageGrab
im = ImageGrab.grabclipboard()
im.save('somefile.png','PNG')
  

Я попытался добавить параметр 'quality=95' в im.save() , но это не сработало. Исходное качество изображения составляет 131 КБ, а сохраненное изображение — 112 КБ.

Комментарии:

1. Как насчет реального качества изображения, а не размера? Было ли это уменьшено?

2. @Alderven Да, реальное качество изображения составляет 131 КБ, а сохраненное изображение — 112 КБ. Качество изображения уменьшено на 19 КБ. Но я не понимаю, почему теряется качество изображений PNG.

3. Как вы получили 131K и 112K ?

4. Возможно, я не совсем ясно выразил свое значение. Я имею в виду, что исходный размер изображения равен 131KB , а размер изображения, полученного после сохранения функцией Python, im.save() становится 112KB . Есть ли функция получше, чтобы сделать размер изображения PNG одинаковым?

5. Как «файл» попал в буфер обмена?

Ответ №1:

Размер файла напрямую не связан с качеством изображения. Это также зависит от того, насколько эффективно кодировщик выполняет свою работу. Поскольку это PNG, процесс выполняется без потерь, поэтому вам не нужно беспокоиться — качество сохраняется.

Обратите внимание, что quality параметр имеет другое значение при сохранении файлов JPEG по сравнению с файлами PNG:

  • В файлах JPEG, если вы указываете более низкое качество, вы фактически позволяете кодировщику отбрасывать больше информации и отказываться от качества изображения в обмен на меньший размер файла.

  • При использовании PNG ваше кодирование и декодирование выполняются без потерь. Качество — это подсказка декодеру относительно того, сколько времени потратить на сжатие файла (всегда без потерь) и о типах фильтрации / кодирования, которые могут подойти лучше всего. Это больше похоже на параметр для gzip like --best или --fast .

Дополнительная информация о формате PNG находится здесь, в Википедии.


Без анализа содержимого двух изображений невозможно сказать, почему размеры отличаются — причин может быть много:

  • Возможно, один кодировщик заметил, что изображение содержит менее 256 цветов, и поэтому решил использовать палитру, тогда как другой, возможно, этого не сделал. Это может привести к различию размеров изображений в 3 раза, но качество будет идентичным.

  • Один кодировщик может использовать больший буфер и тратить больше времени на поиск повторяющихся шаблонов в изображении. Для упрощенного примера представьте, что изображение имеет ширину 32 000 пикселей, и каждая строка такая же, как приведенная выше. Если один кодировщик использует буфер размером 8 КБ, он никогда не сможет определить, что изображение просто повторяется снова и снова на странице, поэтому ему приходится кодировать каждую строку полностью, тогда как кодировщик с буфером 64 КБ может использовать только 1 байт на строку и использовать фильтрацию PNG, чтобы сказать «то же, что и строка выше».

  • Один кодировщик может решить, исходя из простоты кода или из-за нехватки места для кода, всегда кодировать данные в 16-разрядной версии, даже если он может использовать всего 8 бит.

  • Один кодировщик может решить, что он всегда будет сохранять альфа-слой, даже если он непрозрачен, потому что это может упростить очистку кода / данных.

  • Один кодировщик всегда может отказаться от фильтрации, в то время как у другого есть код, необходимый для выполнения sub , up average или Paeth фильтрации.

  • У одного кодировщика может не хватить памяти для хранения всего изображения, поэтому ему, возможно, придется использовать упрощенный подход, чтобы быть уверенным, что он сможет обработать все, что появится позже в потоке изображений.

Я просто придумал эти примеры — не принимайте их за евангелие — я просто пытаюсь проиллюстрировать некоторые возможности.

Комментарии:

1. Спасибо за ваш ответ. Я знаю, что PNG работает без потерь, но почему изображение все еще меньше в процессе сохранения? Мое требование — сохранить исходное изображение, хотя качество такое же, размер меньше.

2. Я добавил еще немного информации к своему ответу. Похоже, вы по-прежнему пребываете в иллюзии, что файлы большего размера означают лучшее качество, а это просто неправда. Представьте изображение размером 1 000×1 000, которое является сплошным красным цветом — я описал это в 25 байтах. Хранить изображение размером 3 МБ со всеми этими повторяющимися rgb (255,0,0) байтами не более точно. Качество такое же, но размер отличается.

3. Думаю, я понимаю, что вы имеете в виду, это очень полезно для меня. Но я требую реализовать программный код, который сохраняет исходное изображение. Какую функцию мне нужно использовать? Возможно, функция Image.save() будет иметь проблему, о которой вы упомянули.

Ответ №2:

Воспроизвести точную копию файла из буфера обмена можно только в том случае, если буфер обмена содержит побайтовую копию оригинала. Этого не происходит, когда содержимое поступает из функции «Копировать» в программе.

Теоретически для этого можно было бы создать программу, установив в объект типа blob копию исходного файла, но это было бы крайне неэффективно и противоречило бы назначению буфера обмена.

Некоторые моменты:
— При копировании в буфер обмена с помощью файлового менеджера в буфере обмена будет ссылка на исходный файл (не на весь файл, который потенциально может быть намного больше оперативной памяти)
— Большинство программ устанавливают содержимое буфера обмена на некоторую «полезную версию» отображаемых или выбранных данных. Это в значительной степени зависит от интерпретации создателем программы.
— Разбор содержимого буфера обмена при чтении изображения снова зависит от прихотей библиотеки, используемой для обработки данных и упаковки их обратно в формат изображения.

Как правило, если вы хотите скопировать файл точно, вам будет лучше просто скопировать исходный файл.

Сказав это: Оцените цель процесса копирования-вставки и решите, являются ли данные, которые вы получаете из буфера обмена, «достаточно хорошими» для намеченной цели. Это, очевидно, зависит от того, для чего вы хотите ее использовать.