#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 копию исходного файла, но это было бы крайне неэффективно и противоречило бы назначению буфера обмена.
Некоторые моменты:
— При копировании в буфер обмена с помощью файлового менеджера в буфере обмена будет ссылка на исходный файл (не на весь файл, который потенциально может быть намного больше оперативной памяти)
— Большинство программ устанавливают содержимое буфера обмена на некоторую «полезную версию» отображаемых или выбранных данных. Это в значительной степени зависит от интерпретации создателем программы.
— Разбор содержимого буфера обмена при чтении изображения снова зависит от прихотей библиотеки, используемой для обработки данных и упаковки их обратно в формат изображения.
Как правило, если вы хотите скопировать файл точно, вам будет лучше просто скопировать исходный файл.
Сказав это: Оцените цель процесса копирования-вставки и решите, являются ли данные, которые вы получаете из буфера обмена, «достаточно хорошими» для намеченной цели. Это, очевидно, зависит от того, для чего вы хотите ее использовать.