Загрузка GIF с сохранением анимации!
Вариант 1 — Если вы не используете ватермарки и скругление углов
Все очень просто и легко + дайте кармы выложить это tips&trics
Открываем файл \engine\modules\image\Image.class.php
Бежим взглядом по коду до вот этого места (примерно строка 148) или ищем сверху по фразе «iWidthDest»
if ($iWidthDest) {
if ($bForcedMinSize and ($iWidthDest>$oImage->get_image_params('width'))) {
$iWidthDest=$oImage->get_image_params('width');
}
/**
* Ресайзим и выводим результат в файл.
* Если не задана новая высота, то применяем масштабирование.
* Если нужно добавить Watermark, то запрещаем ручное управление alfa-каналом
*/
$oImage->resize($iWidthDest,$iHeightDest,(!$iHeightDest),(!$aParams['watermark_use']));
Теперь словами проговорим логику этого куска (там ниже в коде посмотрите что происходит и сразу все поймете):
— Если передана максимальная ширина картинки, то {сжимаем}
/* Стоп но ведь она передается всегда!, Зачем сжимать картинки постоянно? */ -> Изменяем условие, теперь оно звучит так:
— Если передана максимальная ширина картинки (посути, всегда true) И картинка больше максимального размера — тогда {сжимаем}, иначе {сохраняем как есть}
Сам процесс
Обращаем внимание только на первое условие
if ($iWidthDest) {
Правим условие чтобы оно выглядело вот так
if ( $iWidthDest && ( $iWidthDest < $oImage->get_image_params('width')) ) {
Вот и все — теперь она «херит» все действия если картинка меньше максимального размера. Перестает ставить ватермарки и скруглять углы (ибо иначе GIF пересобирется и все бесполезно.) — Подводные камни этого метода «rarjpeg» и прочие хитрости пользователей вплоть до уничтожения вашей системы через дырку в PHP (где-то писали уже про это на хабре), но это не сравнится с радостью при зарузке смишных картинок!)
P.S. Можно проверять не только максимальную_ширину, но и тип файла или даже определять анимированная это gif-ка или нет (на сайте php валяется пример) и т.д.
Вариант 2 — Идея futubra.com
— Можно загружать оригинальный GIF-файл (дописывать в конец имени что-то типа "_orig"), делать его копию и {сжимать} в нашем случае оставлять в нем только первый кадр, а при клике на файл подгружать оригинальное изображение на место этого, делать это можно через javascript напрмерonClick="this.img.src='/file_orig.gif'"
Навеяно все это дело вот этим: futubra.com/posts/467325У них походу, URL оригинальной картинки передается через alt, вот код:
<img src="http://storage.futubra.com/preview/184819/448x806.gif" alt="http://storage.futubra.com/source/184819.gif">
Обработчик пака не раскопал но думаю идея правильная с фоновой подгрузкой изображения и замещением src в превьюшке.
— Вот такая вот идея, и волки сыты и овцы целы
UPD1 — а теперь про аватарки
После внесения изменений в код, фрагмент кода выше, почему то перестали уменьшатся аватарки блогов, странно, но действительно так.Тогда я пришел вот к такому алгоритму: поскольку функции RESIZE не передается никакого флага «аватарка это или нет», только требуемый размер, то я решил схитрить вот таким макаром:
— мы знаем до какого размера надо сжимать картики для постов (у меня это 700 пикс., тема social-jquery) обычно 635 пикс., но чтобы не гадать будем цеплять это значение прямо из конфига и проверять если картинку надо сжать до этого размера — значит эта картинка встаявляется в пост и надо дальше проверить ее — стоил ли ее сжимать вообще или нет, иначе (требуемый размер явно меньше, чем значение в конфиге) значит грузим что то другое -> принудительно сжимаем!
Вот сам код его надо вставить опять в то условие
// print_r(Config::Get('view.img_resize_width')); exit;
//if ($iWidthDest) {
/* Суть такова, если картинка грузится явно не для поста
(проверям размер картинки из конфига) или размер
загружаемой картинки больше чем нужно - то сжимаем */
/*PATCH*/ if ( $iWidthDest < ($oImage->get_image_params('width')) || $iWidthDest < Config::Get('view.img_resize_width') ) {
P.S. Господа, я понимаю, что делаю что то некорректно — я не знаю всей механики этого скрипта и что и как работает, я тыкаюсь в конкретные проблемы и решаю их на месте, если есть какое-то более элегантное решение я только «за» — ткните меня туда носом и я успокоюсь.
Задача ясна — надо позволить пользователям загружать анимированные GIF картинки с достаточной долей безопасности для системы. (Просто с обычными картинками все понятно, они просто пересоздаются и все сторонние вложения в них отчиняются, оставется только исходное изображение, с анимашками сложнее — в них множество заголовков кадров, а при пересоздании берется только первый кадр, остальные теряются,.)
12 комментариев
GIF по прежнему не анимированный.
Т.е. гифка грузить можно без изменения, если её ширина меньше или равна требуемой.
То есть все картинки мы храним на одном сайте-хранилище где просто нет Ничего что мог бы заразить вирус, ни php ни каких других файлов, а основной сайт просто транслирует их (картинки) оттуда.