digital-garden/dev/snippet/Преобразование изображений в Webp.md
Struchkov Mark bd6b7c1492
All checks were successful
continuous-integration/drone/push Build is passing
Дочерние заметки
2024-09-14 23:38:42 +03:00

7.7 KiB
Raw Blame History

aliases tags date zero-link parents linked
maturity/🌱
2024-09-05
../../meta/zero/00 Снипеты на bash

PNG и JPG являются хорошими форматами изображений, которые можно сжать без потери качества. Однако, на сегодняшний день существует более современный формат WebP, который может показать еще более эффективные результаты при сжатии изображений, но с едва заметным ухудшением качества.

В документации WebP перечислено множество параметров, которые повлияют на качество получаемого изображения. Вы можете провести экспериментальный подбор параметров онлайн на сайте https://squoosh.app.

Я вы выбрал для себя следующий набор параметров:

cwebp -mt -af -progress -m 6 -q 80 -pass 10 input.jpg -o output.webp

Это команда преобразует JPG файл input.jpg в файл изображения WebP с именем output.webp. Команда включает несколько опций, которые управляют процессом кодирования:

  • -mt включает многопоточность, что может улучшить производительность  на многоядерных процессорах.
  • -af включает автоматическую фильтрацию, которая применяет алгоритм фильтрации для повышения эффективности сжатия.
  • -progress выводит показывает процент обработки файла.
  • -m 6 устанавливает максимальное количество сегментов, используемых в процессе кодирования, равным 6, что может повысить эффективность сжатия за счет увеличения времени кодирования.
  • -q 80 устанавливает коэффициент качества на 80, который контролирует степень сжатия и влияет на визуальное качество выходного изображения.
  • -pass 10 устанавливает число проходов кодирования равным 10, что может повысить эффективность сжатия за счет увеличения времени кодирования.

Warning

-lossless позволяет использовать сжатие без потерь. Но тогда ваше новое изображение может оказаться существенно тяжелее исходного.

Улучшим скрипт сжатия изображений и добавим преобразование в webp:

find ./images/comp -type f -iregex '.*\.\(jpg\|jpeg\|png\)' -not -iregex '.*no-comp\.\(jpg\|jpeg\|png\)' $option -exec sh -c '
  webp_file="${1/\/images\/comp\//\/images\/webp\/}"
  webp_dir="$(dirname "$webp_file")"
  mkdir -p "$webp_dir"
  cwebp -mt -af -progress -m 6 -q 75 -pass 10 "$1" -o "${webp_file%.*}.webp"
' _ {} \;

Мы берем сжатые изображения из папки comp и преобразуем их в WebP, складывая в отдельную папку webp. Если вы захотите использовать другие параметры сжатия, вы всегда сможете пересоздать изображения с новыми параметрами.

Тесты преобразования

Продолжим наши эксперименты со сжатием. Теперь сожмем наши файл размером в 2,7 мб и 2.2 в формат WebP с разными параметрами качества:

  • -q 90: Размер 325 кб.
  • -q 85: Размер 267 кб.
  • -q 80: Размер 229 кб.
  • -q 75: Размер 200 кб.
  • -q 70: Размер 191 кб.
  • -q 60: Размер 176 кб.
  • -q 50: Размер 163 кб.
  • -q 40: Размер 147 кб.
  • -q 30: Размер 129 кб.
  • -q 20: Размер 115 кб.
  • -q 10: Размер 90 кб.
  • -q 1: Размер 70 кб. Для экстренных случаев. Например, вы заблудились в лесу и надо отправить фото по спутниковой сети 😅

Nginx

Теперь мы научим nginx при запросе изображений сначала пытаться найти WebP файл, и только потом отдавать сжатый PNG/JPG, а если и сжатого нет, то отдавать обычный файл.

Для этого напишем следующий location:

location ~* ^(/blog/ru/content/images/)(.+)\.(png|jpe?g)$ {	
    expires max;
    alias /var/struchkov.dev/ghost/www/images;
    set $webp_image_subdir "/webp/";
    set $basename $2;
    try_files $webp_image_subdir$basename$webp_suffix $uri;
}

Данный location обрабатывает все запросы к адресам, которые начинаются с /images/, за которым следует любое количество символов, затем точка, а затем формат файла png/jpeg/jpg.

Для запросов, соответствующих этому шаблону, выполняются следующие действия:

  • Директива alias указывает путь к локальной директории, из которой будут отдаваться файлы. В данном случае путь к директории /images.
  • Директивы set назначают переменные, которые будут использоваться в последующих директивах. Переменная $webp_image_subdir устанавливается в /webp/, а переменная $basename устанавливается в захваченную подстроку шаблона регулярного выражения (т.е. имя файла без расширения).
  • Директива try_files пытается отдать Webp-версию запрошенного файла изображения, добавляя к переменным $webp_image_subdir и $basename суффикс .webp. Если NGINX сможет найти Webp-версию запрашиваемого файла изображения, он отдаст его. Если он не может найти WebP-версию, то отдаст сжатый JPG/PNG, если и сжатого файла не будет, то отдаст не сжатое.

Мета информация

Область:: ../../meta/zero/00 Снипеты на bash Родитель:: Источник:: Автор:: Создана:: 2024-09-05

Дополнительные материалы

Дочерние заметки