Скидки на решения для государственных организаций

Ресайз картинок на лету


Емельянов Алексей

Дата последнего входа: 26.07.2010 23:01:35
Наименование компании: LEBRAND Creative Russia

Ресайз картинок на лету

Задача - в каталоге у элементов есть большие картинки, нужно выводить несколько их превьюшек разного размера(для каждого элемента по три штуки). Обойти весь каталог скриптом и на генерировать маленькие картинки не вариант(по политическим причинам).

Решение - resize на лету.

Проблемы - нагрузка на железо.

Как выкручивался:

В качестве точки старта выбрал готовую функцию CIBlock::ResizePicture(). Создал скрипт resize.php который будет возвращать браузеру уменьшенную картинку:

<img src="/club/resize.php?i=7840&h=120&w=400" />

i - id картинки в b_file
h - высота
w - ширина

В этот скрипт помещаем нашу функцию, вокруг которой и будут происходить танцы с бубном. Перво-наперво, на всякий случай выключим всё не нужное - define("SM_SAFE_MODE", true) и очистим вывод $APPLICATION->RestartBuffer(). Для каждого типа изображения добавляем хедер - header("Content-type: image/jpeg") - для каждого свой! Теперь уменьшим нагрузку (только если есть frontend) -

header("Pragma: public");//может кэшироваться всеми (прокси-серверами тоже)

header("Cache-Control: max-age=100000000");//закэшируем на сто тысяч мильонов лет


Нюансы: злоумышленники перебирая параметры i и h и w могут заполнить кэш проксирующего сервера, да и вообще сделать не нужную нагрузку на сервер. Решение проблемы - кодировать передаваемые параметры (двустороннее кодирование!):

<img src="/club/resize.php?key=ju09d2f4m9873fd98" />

- ещё хорошо бы ограничить максимальные значения h и w.


пример можно взять здесь, а красиво посмотреть здесь
Max Pryazhevsky
16.03.2010 16:34:56
А CFile::ResizeImageGet() не пробовали?
Емельянов Алексей
16.03.2010 17:14:24
Спасибо за наводку, меня смущает только не превратится ли resize_cache в мусорку, не актуальные превьюшки нужно будет как то удалять.
Иван Левый
16.03.2010 18:27:28
Превьюшки удаляются из этой папки, если удалить сам элемент. Тем эта фукнция и хороша.
Долганин Антон
16.03.2010 19:20:16
PHP - вы что? А если 100 картинок на странице? Тогда у вас будет не 1 хит при запросе, а 101 и серверу просто кранты (количество коннектов апача хотя бы переполнится).

Чему детей учите? smile:)
Оберюхтин Юрий
16.03.2010 20:09:19
Речь о том, что картинки будут кешироваться.
Емельянов Алексей
16.03.2010 20:10:32
100 картинок нормально пережёвываются, к тому же они потом сохранятся в кэше nginx'а, и последующие запросы до апача не будут доходить.

p.s. извините конечно за пошлость, но это как раз тот случай, когда сначало больно, а потом нормально (когда кэш наполнится)
Петров Роман
17.03.2010 05:59:15
мы делаем по-другому:
/pic/80/366346.jpg
80 - это ширина картинки
можно сделать еще и так /pic/80/60/366346.jpg
где 80х60 - то, что должно получиться

при первом обращении создается превью, которое потом сохраняется на диске и счастливо работает уже как статика с диска.

Паносян Артём
20.03.2010 17:27:34
ИМХО, генерировать картинки на лету, можно исключительно ради баловства. На рабочем проекте этого быть не должно. При запросе мелкой картинки с сервера допустима только проверка на её существование. Если нет - создаём и кидаем например в папку temp_pic, которую вы по своим "политическим" причинам можете иногда целиком удалять.

P.S. В скрипте нет проверки на максимум, т.е. если я укажу resize.php?i=7840&h=12000000000000000000&w=400 серверу может поплохеть.
Емельянов Алексей
20.03.2010 22:00:23
прочитай до конца..., а скрипт не боевой и выложил для примера
Роман Забродин
22.03.2010 07:53:38
Есть большой минус с точки зрения безопасности -- можно легко переполнить диск нагененировав скриптом картинок.


Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».