- "[[../../meta/zero/00 Снипеты на bash|00 Снипеты на bash]]"
parents:
linked:
---
Размер изображений составляет существенную часть от размера страницы сайта. Поэтому часто я сжимаю изображения на своих сайтах. В этой заметке рассказываю какими способами я это делаю.
```shell
#!/bin/bash
file=comp.flag
if [ -f "$file" ]; then
option="-newer $file"
fi
find ./images/ -type f -not -path "./images/comp/*" ! -name "*-no-comp.*" $option -iname "*.png" -exec sh -c '
png_file="${1/\/images\//\/images\/comp\/}"
png_dir="$(dirname "$png_file")"
mkdir -p "$png_dir"
cp "$1" "${png_file}"
optipng -o7 "${png_file}"
advpng -z4 "${png_file}"
pngcrush -rem gAMA -rem alla -rem cHRM -rem iCCP -rem sRGB -rem time -ow "${png_file}"
Этот скрипт сжимает изображения без потери качества. Он размещается рядом с каталогом `images`, в котором находятся ваши изображения. Разберемся, как он работает.
Сначала скрипт проверяет, существует ли в текущем каталоге файл `comp.flag`. Если файл существует, он устанавливает значение `-newer $file` в переменную `option`, которая будет использоваться в качестве фильтра для поиска только тех файлов, которые были изменены после даты создания файла `optimg.flag`. Если файл не существует, переменная `option` будет пустой.
Затем скрипт использует команду `find` для рекурсивного поиска файлов в каталоге `images` и его подкаталогах, которые:
-`-type f`. Являются обычными файлами.
- Имеют расширение имени файла `.png`,`.jpeg` или `.jpg`.
-`-not -path`_._Не находятся в указанных каталогах_._В данном случае это каталоги `./images/comp`. Мы будем складывать туда сжатые изображения, и мы не хотим заново по ним проходить поиском и сжимать снова.
-`! -name "-no-comp."`. Оставим возможность не сжимать изображение, если его имя заканчивается на `-no-comp`.
- Для каждого из этих файлов сценарий использует свою команду оптимизации.
Мы не будем затирать оригиналы изображений. Вместо этого мы создадим дополнительную папку `comp` в каталоге `images`, в которую и сложим преобразованные изображения. Создаваемая структура подкаталогов в `comp` будет повторять структуру подкатологов в `images`.
Для файлов PNG сначала используется `optipng` для сжатия с самым высоким уровнем оптимизации (`-o7`). Далее используем `advpng` для дальнейшего сжатия с уровнем сжатия 4 (`-z4`). И наконец `pngcrush` для удаления из файла определенных фрагментов, которые можно безопасно удалить для уменьшения размера файла.
Для файлов JPEG используется `jpegoptim` для их оптимизации со сжатием без потерь (`--all-progressive --strip-all`).
После оптимизации всех подходящих изображений сценарий пересоздает файл `comp.flag`. Это гарантирует, что скрипт будет оптимизировать только те файлы, которые были изменены с момента последнего запуска.
В результате мы смогли сжать png до 2.1 мб, а jpg до 1.9 мб. При этом сохранив исходный размер изображения и без потерь качества.
> [!NOTE]
> Лучшее, на мой взгляд, приложение для сжатия jpg это JPEGmini Pro. Имеет версию cli для серверов. Но к сожалению оно платное. Его результат сжатия 2.2 мб —> 959 кб.