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

+21
2.25K

Нередко посетители сайтов загружают на сервер «слишком большие» изображения. Зачастую оригинальный размер так никогда и не будет востребован, а память на диске он съедает.
Пользователи 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 1 год назад #
Спасибо. Полезно.

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

Код 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 1 год назад #
webtotma, благодарю за обратную связь!
В утилите я сейчас, например, для jpeg при сохранении просто указываю quality из интервала [0,100].
Вы в своём варианте задаёте quality=85 и ещё применяете преобразование в прогрессивный jpeg (--all-progressive).
Как тут правильно выбрать quality, чтобы изображению от этого преобразования хуже не стало? Эти два преобразования как-то взаимосвязаны?
0
webtotma webtotma 1 год назад #
Это просто пример на bash. Все цифры указаны лишь для примера. Использование jpegoptim обусловлено лишь тем, что он умеет делать (когда мне это нужно) lossless-сжатие (т.е без потери качества). А так качество можно указать в параметрах и у mogrify. Использовать прогрессивный jpg или нет - дело вкуса, учитывая его плюсы и минусы.
+1
vikont vikont 7 месяцев назад #

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

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

0
IamB IamB 7 месяцев назад #

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

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

+1
IamB IamB 6 месяцев назад #

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

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


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

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

0
Алексей Т Алексей Т 6 месяцев назад #

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

+1
IamB IamB 6 месяцев назад #

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

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

0
Юран Юран 6 месяцев назад #

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

Изображение

0
IamB IamB 6 месяцев назад #

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

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

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

0
Юран Юран 6 месяцев назад #

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

Изображение

0
IamB IamB 6 месяцев назад #

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

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

0
Юран Юран 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
Юран Юран 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
Юран Юран 2 месяца назад #

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

0
IamB IamB 2 месяца назад #

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

0
Юран Юран 2 месяца назад #

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

Еще от автора

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