Оптимизация размера изображений на сайте

+22
2.93K

Нередко посетители сайтов загружают на сервер «слишком большие» изображения. Зачастую оригинальный размер так никогда и не будет востребован, а память на диске он съедает.
Пользователи InstantCMS 2 знают, что система имеет непростую структуру директории upload, которая ставит некоторых юзеров в тупик при попытке проинспектировать имеющиеся на сайте картинки. Собственно эти обстоятельства и явились неким «вызовом» для написания утилиты, представленной под катом.

Назначение утилиты составить список «слишком больших» изображений и, при необходимости, перезаписать эти файлы с меньшим размером.

Утилита лазает по указанной папке, например, upload/000/u5 или любой другой и смотрит на все картинки. Можно задать типы: jpeg, png, gif. Можно сразу 3 типа, можно 2, можно 1.
«Слишком большие» изображения выбираются:
— либо по размеру файла,
— либо по длине «длинной» стороны изображения.
Например, для изображения 5000х3000px длинная будет 5000px, а для изображения 2200х4000px — 4000px.
Указываем, например, выбирать все, чей размер больше 5 мегабайт, или все, у которых длинная сторона больше 3000px. Запускаете утилиту — получается список. На этом этапе можно и остановиться, и оценить «насколько всё запущено».

Если вы намерены пойти дальше, то инспектировать указанную папку стоит до момента четкого понимания, какие картинки нужно уменьшить и какие задать размеры для перезаписи изображений.

Когда это станет понятно, вы запускаете утилиту по новой. Но уже добавив исполнение нескольких методов в файле app.php для перезаписи.
И утилита перезаписывает отобранные файлы. Т.е. был upload/000/u5/f/1/ddd.jpg размером 5 мегабайт, станет upload/000/u5/f/1/ddd.jpg с шириной 900px или высотой 600px в зависимости от ориентации. И это будет уже не 5 мегабайт, а гораздо меньше.

Все размеры можно выставлять в файле конфигурации data/config.json
Информация по результатам работы утилиты пишется в файл data/app.log, чтобы ничего не потерялось и можно было смотреть сколь угодно долго.

Иллюстрация

По ходу выполнения скрипта можно расставлять метки, чтобы оценить время выполнения отдельных участков скрипта.


О технике безопасности. Изображения — чувствительная часть контента. Сделайте дамп директории, где вы планируете перезапись. Попробуйте выполнить все операции на локальном компьютере, посмотрите устраивает ли вас то, что получилось. Поиграйтесь с утилитой, чтобы четко понимать, что вы делаете.

Это основные моменты доступным языком, саму утилиту вы найдёте здесь, а более формальное описание есть в файле readme.ru.md

+1
webtotma webtotma 4 года назад #
Спасибо. Полезно.

А то я делал в духе:

Код PHP:
  1. find pictures/ -type f -iname "*.jpg" -exec mogrify -resize "800>x600>" {} \; -exec jpegoptim --strip-all --all-progressive -Pptm85 {} \;
Если на серваке, конечно, установлен imagemagick и jpegoptim. Плюс в find можно задать "возраст" файлов для поиска.
0
IamB IamB 4 года назад #
webtotma, благодарю за обратную связь!
В утилите я сейчас, например, для jpeg при сохранении просто указываю quality из интервала [0,100].
Вы в своём варианте задаёте quality=85 и ещё применяете преобразование в прогрессивный jpeg (--all-progressive).
Как тут правильно выбрать quality, чтобы изображению от этого преобразования хуже не стало? Эти два преобразования как-то взаимосвязаны?
0
webtotma webtotma 4 года назад #
Это просто пример на bash. Все цифры указаны лишь для примера. Использование jpegoptim обусловлено лишь тем, что он умеет делать (когда мне это нужно) lossless-сжатие (т.е без потери качества). А так качество можно указать в параметрах и у mogrify. Использовать прогрессивный jpg или нет - дело вкуса, учитывая его плюсы и минусы.
+1
vikont vikont 2 года назад #

Да вы, IamB волшебник!
Обработал утиитой самый проблемный сайт… не поверите, я просто в восторге!
Нашлось 3500 крупных файлов. Утилита их обработала ужав с 14,5 Гб, до 1 Гб за 49 минут!!! Высвобождено 13,5 Гб дискового пространства!
Это просто СУПЕР! Файлы ужались, без видимых потерь качества!
Это все при стандартных настройках сжатия. Я лишь указал параметры для поиска файлов.

Теперь все сервисы сжатия можно выбросить в топку...

0
IamB IamB 2 года назад #

Благодарю за такой отзыв! Да решительности вам не занимать. Но понимаю, что 49 минут ожидания результата были не самыми приятными. Вы после инспектирования получили полную картину с большими файлами. Поэтому уменьшение размера можно было запустить сначала в директории какого-то отдельного пользователя, чтобы оценить скорость работы утилиты. И посчитав, что на обработку файла уходит ~0.86 сек, уже запускать утилиту для всей директории upload, не добавляя себе седины. Но, победителей не судят!

Пользователи утилиты! Если этот продукт вас выручил, поставьте  звездочку на github

+1
IamB IamB 2 года назад #

Поскольку в версии 2.15.0 

Добавлена возможность конвертации GIF как GIF, сохраняя анимацию. Необходимо расширение PHP imagick;


то теперь imagick уже не является «непозволительной роскошью» на типичном сервере для InstantCMS. В связи с этим я решил добавить в свою утилиту возможность уменьшать анимированные  gif. Работа увлекла и в результате я переписал утилиту, изменив её внутреннюю организацию. Использование самой утилиты для пользователя осталось прежним. Предыдущая версия утилиты осталась на своем месте, а для новой создана ветка imagick, где её можно взять.

Пожелание: при работе с анимированными  gif обращайте внимание не только на размер файла, но и на размеры сторон изображения. Имеет смысл создать отдельный файл конфигурации(config.json) только для gif изображений, не пытаясь решить все вопросы за один раз.

0
Алексей Т Алексей Т 2 года назад #

Скачал, спасибо посмотрим

+1
IamB IamB 2 года назад #

Скачал, спасибо посмотрим

Если у вас есть кому сделать код-ревью, был бы признателен. Свежая версия на github.

0
Yuran Yuran 2 года назад #

В корне сайта на icms создал папку reduction, склонировал в нее с гита эти скрипты, ничего не настраивал, запускаю с консоли и ничего не происходит.  Подскажите пожалуйста что не так делаю. Imagick и php-imagic установлены. Версия php 8.0.9 

Изображение

0
IamB IamB 2 года назад #

запускаю с консоли и ничего не происходит.

Если утилита отработала как надо, в консоли и не должно ничего быть. Все результаты пишутся в файл reduction/data/app.log (это по умолчанию). В тексте поста об этом написано, посмотрите повнимательнее содержание readme.ru.md

Вот тема на форуме, которую тоже стоит посмотреть.

0
Yuran Yuran 2 года назад #

Дописал в app.php код для типового применения, запустил из консоли, проверил лог, работает нормально, картинок на сайте немного, но тем не менее он что то нашел и обработал. А подскажите откуда на сервере могут появляться огромные изображения? Я посмотрел в компоненте «загрузка изображений» выглядит так, вроде должно автоматом уменьшаться до этих значений...  Извините если туплю:))

Изображение

0
IamB IamB 2 года назад #

откуда на сервере могут появляться огромные изображения?

Если на сайте есть пользователи и вы выставили сохранять оригинальные изображения.

0
Yuran Yuran 2 года назад #

Появилась необходимость проверить большие изображения… Почему то все время в app.log вижу такое:

  1. [2022-05-17 19:37:25.373] [Info] Заданы значения:
  2. {
  3. "folderPath": "..\/upload-t",
  4. "mode": "ImageSide",
  5. "maxFileSize": 80000,
  6. "maxImageSide": 800,
  7. "maxWidth": 400,
  8. "maxHeight": 250,
  9. "ableTypes": [
  10. "jpeg",
  11. "png",
  12. "gif"
  13. ],
  14. "quality": {
  15. "jpeg": 75,
  16. "png": 6
  17. }
  18. }
  19. [2022-05-17 19:37:25.373] [Error] navt\Reduction\Reduction::getList
  20. По указанному пути ../upload-t нет директории.
  21.  

сожержимое config.json по умолчанию… папки data и vendor в корне сайта, файл app.php тоже в корне сайта. Ставил все как написано здесь github.com/navt/reduction/blob/master/readme.ru.md#%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5

Подскажите пожалуйста что где поправить? PHP 8.1.3 

0
IamB IamB 2 года назад #

В инструкции на github есть строчка

Отредактируйте data/config.json и app.php в соответствии с вашей текущей задачей.

В data/config.json указана директория ../upload-t ('это директория для моего проекта), поправьте на ../upload

0
Yuran Yuran 2 года назад #
  1. [2022-05-17 20:29:46.239] [Info] Заданы значения:
  2. {
  3. "folderPath": "..\/upload",
  4. "mode": "ImageSide",
  5. "maxFileSize": 80000,
  6. "maxImageSide": 800,
  7. "maxWidth": 400,
  8. "maxHeight": 250,
  9. "ableTypes": [
  10. "jpeg",
  11. "png",
  12. "gif"
  13. ],
  14. "quality": {
  15. "jpeg": 75,
  16. "png": 6
  17. }
  18. }
  19. [2022-05-17 20:29:46.239] [Error] navt\Reduction\Reduction::getList
  20. По указанному пути ../upload нет директории.
  21.  
0
IamB IamB 2 года назад #

Предложу 2 варианта: 1. перечитать инструкцию и настроить рабочий для вашего случая путь в data/config.json либо 2. предоставьте доступ к сайту, буду смотреть.

0
Yuran Yuran 2 года назад #

Написал доступ в ЛС.

0
IamB IamB 2 года назад #

Должно было быть просто upload. Скрипт отработал, смотрите data/app.log

0
Yuran Yuran 2 года назад #

О, спасибо огромное✋🤝

Еще от автора

Google Таблицы
Поле призвано упростить работу с таблицами. Можно создавать таблицы во встроенном визуальном редакторе, но это занятие как минимум трудоемкое.
Создание таск-трекера своими(почти) руками
Этот пост появился благодаря теме на форуме. Поразмышлял, пописал код, поставил опыты и. думаю, процентов на 80 решил задачу с форума.
Логгер для проекта
По случаю написал логгер. Конечно, можно было взять готовый, поскольку только ленивые их не писали.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.