Как я картинки на сайте пережимал: TinyPNG из командной строки

· автор BaRoN · На чтение уйдёт 4 минут · (674 слов)

С давних пор в Linux для конвертации картинок используется пакет ImageMagick, а точнее, программа convert. Например, когда мне надо залить какие-нибудь фотографии на какой-нибудь идиотский сайт, ограничивший размер вложений парой мегабайт, я использую ImageMagick. В истории через Ctrl+R находится волшебная строчка, которую решительно невозможно выучить наизусть. Подумываю даже написать для неё алиас, но раз уж я начал писать эту заметку в бложик, алиас больше не нужен: всегда смогу найти её тут. Ладно, конец интриге. Вот она, строчка:

for i in *.JPG; do convert "$i" -define jpeg:extent=1500kb "out/$i" ; done

Однако, у этой строчки есть серьёзный недостаток: качество картинки не контролируется, плюс вообще сильно зависит от начальных параметров, плюс иногда так бывает, что надо пережать картинку по размеру меньше, чем 1.5 Мб. Как быть?

На помощь приходит замечательный сервис TinyPNG. Эти ребята автоматизировали вызов pngcrush и иных утилит, научившись тем самым извлекать максимум из алгоритмов сжатия PNG. PNG - как известно, это картинки без потери качества, так что результирующая картинка идентична оригинальной (но будет использовать другой набор фильтров и опций сжатия). Что ещё сказать? Математика - царица полей, при помощи подбора фильтров и алгоритмов сжатия, размер файла порой уменьшается до 20%, а средняя экономия на обычном файле, вышедшем из недр Photoshop, составляет 10%. Также они преобразовывают 24-битные PNG в 8-битные (с потерей качества, но малозаметной простым смертным). Качество получается несравнимо лучше, чем когда кино пытаются ужать в гифку. :)

Пару лет назад сервис также научился обрабатывать JPEG. Как JPEG в PNG ни конвертируй, а JPEG всё равно будет меньше (на самом деле нет, например чёрный квадрат в PNG с высокой вероятностью будет компактнее)! Поэтому JPEG они конвертируют снова в JPEG, оптимизируя как картинку, так и параметры сжатия. Тоже выжимают процентов 10 обычно.

Простые смертные таскают JPG или PNG файл через проводник на окошко в браузере Internet Explorer, но сильные и ловкие программисты могут воспользоваться API, предоставляемым сервисом. К сожалению, количество вызовов API ограничено 500 штуками в месяц. Сайт travelfaqs.ru, который я до сих пор ещё обрабатываю, содержит в себе тысячи изображений, поэтому обработка их вручную не вариант. Даже если нанять филиппинца или школьника через какой-нибудь сервис с заданиями, выйдет дорого. Для таких случаев у TinyPNG есть возможность снять ограничения за небольшие деньги. Честно признаюсь, я плохой человек, поэтому не плачу им денег. Но вы - можете заплатить, возможно это будет правильно.

Итак, поскольку количество попыток сжатия у нас ограничено, нам важно не пытаться подсунуть сервису уже пережатую картинку. Как это понять? Я это делаю очень просто. Если картинка старая (например, старше трёх месяцев, когда я начал работу над сайтом), значит - непережатая. Тут всё просто. Тогда задача упрощается до «найти 500 jpg-файлов, которые не менялись в течение последних 90 дней, по одному обработать их через tinypng и заменить старые файлы обработанныими».

export TINYPNG_API_KEY="A.................9"
for i in `find /home/travelfaqs.ru/public_html/uploads -mtime +90 -name '*.jpg' | head -n 500`; do echo $i && rm -f /tmp/t.jpg && tinypng $i /tmp/t.jpg && mv /tmp/t.jpg $i; done

Итак, сначала скрипт определяет 500 jpg файлов, дата изменения которых в прошлом, 90 или больше дней назад. Потом выводит это на экран, удаляет временный файл (если его не удалить, tinypng не отработает), пережимает старый файл во времнный, и переносит временный файл на место старого. Само собой, последнее предложение повторятеся 500 или менее раз. Временный файл удаляется «на всякий случай», потому что иногда бывают форс-мажоры (например, сервис tinypng был недоступен). Если что-то пошло не так, то просто старый файл остаётся без изменений (и дата модификации у него всё ещё в прошлом, то есть он пережмётся в следующий заход).

Качество картинок я проверять перестал. С виду мне они всегда казались идентичными, так что я сначала посмотрел-посмотрел на это дело, а потом перестал.

Чего хотелось бы, так это статистики по оптимизации, но нет её, такой статистики.

И маленький совет для нехороших людей и скупердяев вроде меня. Если начать оптимизацию 30 ноября, а продолжить 1 декабря, то одним API-ключом можно пережать 1000 файлов. Итого достаточно, например, 20 ключей на практически любой сайт. Хотя, конечно, правильнее заплатить разработчикам $25, и пользоваться сервисом без лимитов и ограничений целый год. Возможно, на приносящих прибыль сайтах, я именно так и поступлю.

Полезное