Недавно мне задали такой вопрос:
Иван, как-то довелось делать resize png-картинки в Gimp. По сравнению с Photoshop качество хуже. Можешь тут подсказать?
Фотошопа у меня нет, сравнить не могу, поэтому попробую рассмотреть вопрос несколько по другому — какие способы ресайза мы имеем в Linux, пусть не «из коробки», но с минимальными трудозатратами. И что нам со всем этим богатством делать…
Сразу замечу, что выбор методов ресайза зависит не столько от формата, сколько от характера исходного изображения, так что все, написанное ниже следует читать не как прямое руководство к действию, а как подсказку, в каком направлении копать.
Для начала, чтобы много не писать о сути проблемы вообще, сошлюсь на хабрастатью «Ликбез: методы ресайза изображений». Она старая, но в плане основ и теории достаточно хорошо всё описывает. Более подробно, но на английском, можно почитать на сайте ImageMagick: «Resizing or Scaling», «Resampling Filters» и «Resampling by Nicolas Robidoux». Если Photoshop не использует новейшие достижения искусственного интеллекта (это не шутка, различные AI-методы сейчас активно применяются в обработке изображений), то правильный выбор фильтров и параметров, будем надеяться, позволит получить результат не хуже.
Что же касается формата PNG, то тут есть два соображения: во-первых, область применения — как правило, в PNG сохраняют не фотографии, а изображения с чистыми цветами и четкими границами, а во-вторых, применимость его к финальному результату — запросто можно при уменьшении картинки получить файл большего объема…
В общем, я взял два типичных, как мне кажется, случая, когда применяется именно этот формат: уменьшение скриншота (небольшое, чтобы можно было говорить о читаемости) и увеличение иконки (тут — в разы). Экспериментировать я буду с применением GIMP и ImageMagick.
Disclaimer: я не специалист в данной теме и все, что могу — потыкаться с точки зрения продвинутого юзера. Вышеприведенные ссылки могут стать отправной точкой для желающих разобраться по настоящему.
Уменьшение скриншота
Вот такой скриншот диалогового окна собственно GIMP и собственно изменения размеров. В оригинальном разрешении:
Ширина в оригинале — 415px. Ужимать будем до 320px, то есть, если очень грубо, на 20%. Точно такая же картинка вверху этого поста, но сделанная движком браузера автоматически, что там, какие алгоритмы использованы — то мне неведомо.
GIMP
GIMP предлагает пять вариантов интерполяции:
- Нет
- Линейная
- Кубическая
- Без гало
- Мало гало
Обратившись к документации, мы узнаем, что «Нет» — означает то, что обычно в источниках называется «метод ближайшего соседа», а «линейная» и «кубическая» чаще называются «билинейной» и «бикубической» соответственно. Какой алгоритм используется в двух последних вариантах — непонятно, судя по всему, подавление гало работает уже поверх собственно интерполяции… Так же возможно, это какие-то модификации метода Lanczos, который был на их месте в старых версиях GIMP.
Пять вариантов достаточно мало, для того, чтобы все попробовать. Что же мы получим?
Разницу между линейной и кубической уловить трудно, а последние два варианта — с гало и без — вообще от кубической на глаз не отличаются, поэтому я их приводить не стал. Однако есть еще момент — размеры файлов. Для полноты картины я сравнил размеры не только файлов, которые мне сохранил GIMP, но и их же после оптимизации программой optipng, которая не меняет пиксели, только перепаковывает.
Получилось:
Файл | Пиксели | Байты | Опт. |
---|---|---|---|
source.png (исходный файл) | 415x361 | 34K | 25K |
gimp-none.png (интерполяции нет) | 320x278 | 25K | 16K |
gimp-linear.png | 320x278 | 37K | 24K |
gimp-cubic.png | 320x278 | 43K | 28K |
gimp-wo-galo.png (без гало) | 320x278 | 40K | 27K |
gimp-s-galo.png (мало гало) | 320x278 | 43K | 28K |
Итак, мы отчетливо видим, что уменьшение скриншота в большинстве случаев увеличивает его размер. Что, впрочем, для формата PNG ожидаемо. В целом, выводы можно сделать такие:
-
Метод ближайшего соседа для уменьшения скриншотов не годится совсем — надписи не читаемы.
-
Если качество линейной интерполяции нас устраивает, берем ее — она не только выполняется быстрее, но и дает результат меньшего объема.
-
Если нам нужно максимальное качество, в GIMP выбираем вариант «Без гало» — за счет более резкой картинки (а именно это и делает подавление гало) файл лучше сжимается.
И помним, что на другой исходной картинке результаты могут отличаться существенно, так что стоит экспериментировать.
ImageMagick
Хорошая новость заключается в том, что ImageMagick предоставляет больше вариантов ресайза. Плохая — в том, что их намного больше.
Команда convert -list filter
на моей системе выдает список из 31 пункта. Но это еще не все — помимо оператора -resize
есть еще
-distort Resize
… Так что количество вариантов нужно умножать на два. А еще у многих фильтров есть настраиваемые параметры, а еще…
В общем, при углублении в тему документация ImageMagick подбрасывает все новые и новые уровни. В рамках этого поста я пройдусь
по верхам и параметры по умолчанию менять не буду.
Чтобы посмотреть все варианты, я воспользовался таким скриптом:
На самом деле -resize
без указания фильтра — это то же самое, что -filter Mitchell -resize
, а -distort Resize
—
-filter Robidoux -distort Resize
. А вот -adaptive-resize
— это отдельный режим, где обработка должна базироваться
на данных самой картинки (в документации тут не все ясно).
Итого у меня получилось 65(!) вариантов, все я, естественно, приводить не буду. Начнем с умолчательных:
Далее проверим алгоритмы, которые должны соответствовать GIMP’овским (на самом деле не совсем).
-filter Point
— это метод ближайшего соседа, как из него -distort
получил нечто приемлемое — мне не очень понятно.
Курьеза ради, и чтобы не создалось впечатления, что -distort
всегда лучше, чем -resize
, приведу варианты
с фильтром Sinc
:
Завершу этот парад почти одинаковых картинок еще двумя фильтрами, которые показали приемлемые результаты по размеру выходного файла.
Теперь о размерах выходных файлов подробно (напомню, что исходный файл был 34K/25K):
Фильтр | -resize | -distort | ||
---|---|---|---|---|
Байты | Опт. | Байты | Опт. | |
-resize по умолчанию (Mitchell) | 43K | 29K | ||
-distort по умолчанию (Robidoux) | 46K | 31K | ||
-adaptive-resize | 36K | 23K | ||
Point (ближайший сосед) | 25K | 17K | 37K | 24K |
Triangle (линейная) | 39K | 26K | 42K | 28K |
Cubic | 41K | 30K | 41K | 30K |
Lanczos2 | 47K | 31K | 47K | 32K |
Lanczos2Sharp | 46K | 31K | 47K | 32K |
Sinc | 67K | 46K | 67K | 39K |
Box | 30K | 19K | 38K | 24K |
Hermite | 39K | 25K | 40K | 26K |
Выводы:
- Если очень нужно уменьшать разрешение скриншота в PNG, то
-adaptive-resize
; - Но лучше вообще без этого обойтись, например, в вебе просто задав размеры у тега
IMG
и отдав масштабирование на откуп браузеру — трафик так можно сэкономить заметно.
Это все, конечно, оносится только к случаям, подобным рассмотренному — когда размеры картинки ужимаются процентов на 20, чтобы,
скажем, вписаться в верстку. При сильном уменьшении про читаемость можно просто забыть и использовать простейшие методы, дающие
минимальный выходной файл. Кстати, на этот случай в ImageMagick есть еще и оператор -thumbnail
, который работает еще быстрее
и грубее, чем -resize
, а заодно выбрасывает всю метаинформацию.
Увеличение иконки
Здесь я решил поиздеваться над иконкой Darktable, в оригинале — 64x64px.
Будем увеличивать ее в 5 раз по линейным размерам, т.е. в 25 по площади — до 320x320px. Вот так это может сделать браузер:
GIMP
А вот что нам предлагает GIMP:
В режиме «Нет интерполяции» мы ожидаемо видим увеличение каждого пикселя, а в режиме «Линейная» — какое-то мыло. «Без гало» дает нам мыло немножко по краям подшарпленое, что, кстати, наиболее похоже на вариант от браузера. Что же до оставшихся «Кубической» и «Мало гало» — я не смог их отличить от «Линейной», даже быстро переключаясь с одной на другую.
Файл | Пиксели | Байты | Опт. |
---|---|---|---|
darktable.png (исходный файл) | 64x64 | 6.2K | 6.2K |
gimp-none.png (интерполяции нет) | 320x320 | 9.7K | 9.4K |
gimp-linear.png | 320x320 | 68K | 68K |
gimp-cubic.png | 320x320 | 75K | 75K |
gimp-wo-galo.png (без гало) | 320x320 | 72K | 72K |
gimp-s-galo.png (мало гало) | 320x320 | 76K | 75K |
Выводы? Ну, для демонстрации пиксель-арта первый вариант может быть полезен. В остальных случаях браузер справляется не хуже, а объем меньше на порядок.
ImageMagick
Скриптом, аналогичным предыдущему, удалось получить множество вариантов. Но ничего прямо так принципиально отличающегося в лучшую сторону. Вероятно, без применения каких-нибудь AI-методов (т.е. распознавания и перерисовывания по сути) ничего принципиально улучшить и не получится. Поэтому ограничусь только тремя примерами:
Третий пример, если кто не догадался, вставлен забавы ради.
Как можно видеть, -adaptive-resize
справляется, как минимум, не хуже GIMP’а… Что же по размерам файлов?
Фильтр | -resize | -distort | ||
---|---|---|---|---|
Байты | Опт. | Байты | Опт. | |
-resize по умолчанию (Mitchell) | 74K | 70K | ||
-distort по умолчанию (Robidoux) | 77K | 73K | ||
-adaptive-resize | 67K | 61K | ||
Point (ближайший сосед) | 11K | 9.6K | 69K | 66K |
Parzen | 88K | 84K | 78K | 74K |
Sinc | 111K | 107K | 131K | 130K |
Я не стал вставлять картинку с -filter Point -resize
, поскольку она ожидаемо неотличима от того, что делает GIMP без интерполяции.
А еще такой же результат позволяют получить операторы -sample
и -scale
, только быстрее. Так же, как и -thumbnail
— это максимально
упрощенные и тупые варианты ресайза.
Итого
-
Во-первых, формат PNG применяется для тех случаев, когда нам важно сохранить каждый пиксель как он есть. Т.е. любое масштабирование для таких картинок противопоказано. Именно для картинок как таковых, а не для формата. Если мы храним в PNG что-то хорошо масштабируемое, возможно, мы что-то делаем не так.
-
Как только мы вместо резких переходов получаем сглаживание или размытие, файлы раздуваются непотребно. И это уже особенность формата, да, сжатие которого рассчитано на одноцветные области.
-
Если всё же необходимо ресайзить PNG и именно в PNG, я бы, пожалуй, первым делом попробовал оператор
-adaptive-resize
пакета ImageMagick. А если результат не устраивает — прогнал бы скриптом прочие варианты фильтров. Можно, конечно, заморочиться и на подгонку их параметров, но боюсь, мои глаза не справятся с отловом тончайших отличий в огромном количестве файлов. -
GIMP, честно говоря, удивил бедностью возможностей — уж с десяток алгоритмов могли бы и завезти…
PS. Для удобства оригиналы ссылкой: скрин и значок. Желающие могут попробовать поиграть с их размерами в разном другом софте, включая фотошоп.