Оптимизация картинок для блога
В ходе знакомства с возможностями движка блога столкнулся с проблемой большого размера изображений. Большую часть фотографий я делаю на телефон, камера которого имеет разрешение 13 мегапикселей. Получаются фотографии формата JPEG и разрешением 4208×3120. Размер таких фотографий сильно зависит от содержимого, обычно — 1-5Мб. Ниже пример картинки, её размер — 4Мб, что многовато для веба.

Исходное изображение 4Мб
Та же самая картинка после оптимизаций имеет размер 370Кб — примерно в 10 раз меньше.

Оптимизированное изображение 370Кб
Визуальной разницы нет, а польза налицо.
Как это сделать
1. Уменьшаем изображение
Я уменьшаю изображения до 2880×1800 — это разрешение экрана моего ноутбука; если картинка меньше, то ничего не делаю. Для этого использую утилиту из набора библиотеки ImageMagick. На MacOS установить её можно следующей командой (требуется наличие Homebrew):
 |  | 
Команда для уменьшение изображения:
 |  | 
\> в значение параметра -resize предписывает не изменять размер изображения, если оно помещается в прямоугольник заданного размера.
После уменьшения разрешения, размер картинки составляет 1,4Мб.
2. Понижаем качество изображения
Коэффициент качества при сжатии JPEG выбирается в диапазоне от 1 до 100.
В зависимости от содержимого картинки, снижение качества со 100 до значений между 80 и 60 визуально незаметно.
Для своих целей я выбрал значение 77 — я рассчитываю, что при таком значении понижение качества не будет заметно для любых картинок.
Для изменения качества можно использовать ту же утилиту convert:
 |  | 
Или можно объединить с шагом №1:
 |  | 
После понижения качества изображения, её размер уменьшился до 515Кб.
3. Изменяем тип компрессии
Библиотека mozjpeg является одной из самых эффективных для этой цели.
На MacOS устанавливается через brew:
 |  | 
Последняя команда создаёт символьную ссылку на исполняемый файл утилиты cjpeg, чтобы его можно было запускать без указания полного пути.
Имя изменено на mozcjpeg, чтобы избежать конфликта с одноимённой утилитой библиотеки libjpeg.
Так как утилита mozcjpeg умеет изменять качество изображения, я использую её для этой цели, вместо convert.
 |  | 
Более того, понижение качества через mozcjpeg даёт лучший результат.
Если сначала понизить качество с помощью convert и потом применить сжатие mozjpeg, то получим изображение размером 482Кб.
А если изменять качество с помощью mozcjpeg, то результатом будет 370Кб.
Помимо изменения качества, по-умолчанию также применяются параметры -optimize (ради чего эта библиотека и используется) и -progressive (позволяет загружать картинку более плавно — пример).
Более подробно можно посмотреть в инструкции к утилите.
Экономим на спичках
Дополнительно можно удалить информацию в EXIF.
Например, это можно сделать с помощью параметра -strip утилиты convert.
Но я не стал этого делать.
Автоматизируем
Чтобы избавиться от рутины я написал небольшой скрипт, который выполняется перед каждым коммитом и обрабатывает новые или изменённые изображения.
Если в названии картинки есть подстрока .noopt., картинка пропускается — это значит она мне нужна необработанная, как картинки в этой заметке.
Также создаются бекапы каждого изображения, которые игнорируются в .gitignore.
Чтобы скрипт работал, его нужно поместить в исполняемый файл .git/hooks/pre-commit.
 |  | 
Берегите трафик!