Blog. Just Blog

Делаем быстрые и красивые превьюшки

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
При работе с графикой, а именно при создании различных онлайн-галерей, при работе с прикрепленными к статьям файлами в CMS, требуется создание так называемых превьюшек - пропорционально уменьшенных копий изображений. Они могут создаваться динамически или храниться на диске в виде отдельных файлов, все зависит от конкретной задачи. Рассмотрим несколько способов создания превьюшек и сравним их производительность.

Сравнение способов создания превьюшек
Сравнение способов создания превьюшек

Для тестов была взята фотография размером 3468 х 2736 пикселов, глубина цветности 24 бита. Цель - разными способами сделать из нее превьюшку размером 200 x 150 пикселов и сохранить результат в файл JPG с наилучшим качеством. Тестовые фрагменты кода максимально облегчены, все размеры и названия файлов захардкодены прямо в исходники. Время выполнения тестов и объем занятой памяти соответствуют моему ноутбуку, эти значения приведены только для сравнения, так что не удивляйтесь, если ваши цифры будут отличаться.

Самый быстрый способ создать превьюшку с изменением размера изображения - функция PHP imageCopyResized. Тестовый код приведен ниже, результат можно посмотреть на первой картинке. Хоть скорость и максимальная, но результат оставляет желать лучшего: превьюшка получилась зернистой. Размер файла превьюшки получился около 39 килобайт.
  1. $im=imageCreateFromJPEG('image.jpg');
  2. $tn=imageCreatetrueColor(200,150);
  3.  
  4. // Изменить размер исходного изображения до размера превьюшки
  5. imageCopyResized($tn,$im,0,0,0,0,200,150,3468,2736);
  6. imageDestroy($im);
  7.  
  8. // Сохранить результат в файл
  9. imageJPEG($tn,'resized.jpg',100);
  10. imageDestroy($tn);
Использование функции PHP imageCopyResampled дает на выходе самый красивый результат, превьюшка сглаженная, никаких выбивающихся пикселов и артефактов. Но какой ценой это было достигнуто! Изменение размера изображения и его обработка заняли более 3 секунд. Размер файла превьюшки получился минимальный - около 31 килобайта. Тестовый код приведен ниже.
  1. $im=imageCreateFromJPEG('image.jpg');
  2. $tn=imageCreatetrueColor(200,150);
  3.  
  4. // Изменить размер исходного изображения до размера превьюшки
  5. imageCopyResampled($tn,$im,0,0,0,0,200,150,3468,2736);
  6. imageDestroy($im);
  7.  
  8. // Сохранить результат в файл
  9. imageJPEG($tn,'resampled.jpg',100);
  10. imageDestroy($tn);
Теперь попробуем хитрый комбинированный способ, который объединяет в себе оба вышеописанных способа. Хитрость заключается в том, чтобы сперва быстро изменить размер первоначальной картинки функцией imageCopyResized до такого размера, когда изображение еще не будет сильно деформировано, а затем выполнить доводку полученного промежуточного изображения до размера превьюшки функцией imageCopyResampled. Результат однозначно радует: скорость выполнения кода приближена к первому примеру, а качество полученного изображения почти аналогично второму. Можете сравнить второй и третий примеры на картинке. Оставшаяся небольшая зернистость наоборот идет на пользу, создавая некоторый эффект резкости. Размер файла превьюшки получился около 33 килобайт, то есть опять же максимально приближено к изображению лучшего качества. Но на создание промежуточного изображения тратится дополнительная память, поэтому не забывайте в реальном приложении вовремя освобождать ненужные ресурсы.
  1. $im=imageCreateFromJPEG('image.jpg');
  2. $ds=imageCreatetrueColor(600,450);
  3.  
  4. // Изменить размер исходного изображения до промежуточного
  5. imageCopyResized($ds,$im,0,0,0,0,600,450,3468,2736);
  6. imageDestroy($im);
  7.  
  8. $tn=imageCreatetrueColor(200,150);
  9. // Изменить размер промежуточного изображения до размера превьюшки
  10. imageCopyResampled($tn,$ds,0,0,0,0,200,150,600,450);
  11. imageDestroy($ds);
  12.  
  13. // Сохранить результат в файл
  14. imageJPEG($tn,'combined.jpg',100);
  15. imageDestroy($tn);
Есть еще один способ - воспользоваться для конвертирования изображений установленным на сервере программным обеспечением. Это может дать еще больший выигрыш в скорости и качестве, но не на всех хостингах эти приложения установлены или доступны для запуска из пользовательского проекта. Так что этот способ в рамках статьи я рассматривать не буду.

К чему это я все затеял? Да просто опробовал еще одну возможность оптимизации. В галерее домашней странички Васи Пупкина разница между 3 и 0.6 секундами погоды не сделает, а в высоконагруженных проектах, и особенно если требуется создавать изображения "на лету", любой выигрыш во времени будет ощутим.

Поделиться ссылкой ВКонтакте
Просмотров: 8153 | Комментариев: 3

Метки: PHP, графика
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Тремор (11.12.2010 в 01:47):
ipSlicer, Вася априори не поймет в чем дело то
Вадим (01.12.2010 в 18:32):
Спасибо! Как то и не задумывался об этом никогда, принимаем на вооружение.
ipSlicer (01.12.2010 в 15:42):
"В галерее домашней странички Васи Пупкина разница между 3 и 0.6 секундами погоды не сделает" - сделает-сделает. Вася обычно по 100500 картинок загоняет на сайт, а потом кричит что хостинГ :), ибо васю тупо рубят по max_execution_time. Так что метод подойдет и васе для генерации превьюшек "на лету". Спасибо за тесты.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.11 сек. / MySQL: 2 (0.0078 сек.) / Память: 4.5 Mb
Наверх