2 способа создания thumbnail на php
Все кто когда-то писал различного рода CMS от полноценных до простых скриптов галерей, сталкивались с проблемой создания уменьшенных копий изображений или thumbnail`ов на php (в народе известны как “превьюшки”).
Картинки на входе (которые надо уменьшить) могут быть с различными соотношениями между длинной и шириной, а на клиентской стороне скрипта (то, что видит посетитель сайта), задаются фиксированные размеры области вывода. Наша задача заключается в том, чтобы создать из первого – второе с помощью php.
Тут следует упомянуть еще один момент, который будет непосредственно рассмотрен в этот статье. На самом деле способов создания thumbnail`ов на php существует два (еще подскажете еще один, буду признателен):
- Изменение масштаба изображения (сжатие размеров).
- Выделение области, которая будет выводиться.
С первым все понятно, так как это самый популярный прием. Второй же случай встречается реже и не является автоматическим (нужно чтобы человек выделил область, из которой будет делаться превьюшка).
Но давайте обо всем по порядку. Начнем с первого способа.
Изменение масштаба.
Тут на самом деле не стоит изобретать велосипед, так как проблема эта давно уже изучена и решена помногу раз. Поэтому я просто выложу функцию, которая все делает сама и приведу небольшой комментарий.
<? function img_resize($src, $dest, $width, $height, $rgb = 0xFFFFFF, $quality = 100) { if (!file_exists($src)) { return false; } $size = getimagesize($src); if ($size === false) { return false; } $format = strtolower(substr($size['mime'], strpos($size['mime'], '/') + 1)); $icfunc = 'imagecreatefrom'.$format; if (!function_exists($icfunc)) { return false; } $x_ratio = $width / $size[0]; $y_ratio = $height / $size[1]; if ($height == 0) { $y_ratio = $x_ratio; $height = $y_ratio * $size[1]; } elseif ($width == 0) { $x_ratio = $y_ratio; $width = $x_ratio * $size[0]; } $ratio = min($x_ratio, $y_ratio); $use_x_ratio = ($x_ratio == $ratio); $new_width = $use_x_ratio ? $width : floor($size[0] * $ratio); $new_height = !$use_x_ratio ? $height : floor($size[1] * $ratio); $new_left = $use_x_ratio ? 0 : floor(($width - $new_width) / 2); $new_top = !$use_x_ratio ? 0 : floor(($height - $new_height) / 2); $isrc = $icfunc($src); $idest = imagecreatetruecolor($width, $height); imagefill($idest, 0, 0, $rgb); imagecopyresampled($idest, $isrc, $new_left, $new_top, 0, 0, $new_width, $new_height, $size[0], $size[1]); imagejpeg($idest, $dest, $quality); imagedestroy($isrc); imagedestroy($idest); return true; } ?>
На вход этой функции подается два имени файлов: $src и $dst. Исходный файл и имя файла превьюшки, который будет создан. Кроме этого нужно передать размеры thumbnail`а на выходе. Параметр rgb задает цвет фона результирующей картинки, а quality ее качество (значит и размер файла thumbnail`а). Вот и все. Тут просто.
Вырезалка
А вот тут все уже чуть сложнее и интереснее. Здесь наша задача будет выполняться в два шага.
- Выделение области изображения для создания thumbnail`а.
- Создание по этим параметрам самого файла thumbnail`а.
На первом нам очень помогает библиотека jQuery, которая делает этот процесс более интерактивным (представляете, каково было бы вручную вводить координаты области на картинке?).
Для создания интерактивного элемента выделения области на изображении мы воспользуемся библиотекой интерфейсов от jQuery Resizable.
С документацией по этому компоненту всегда можно ознакомиться на ее сайте, но применение этого компонента, с которым я встретился, было довольно необычным.
Сначала я приведу пример, а потом расскажу принцип работы. Итак, посмотрите демонстрацию.
Принцип работы такой… Основное изображение кладется на фон div`а. Поверх него ставится еще один div, у которого можно менять размеры и положение. При изменении положения или размеров их значения передаются в скрытые поля формы (в примере они просто выводятся в span`ы). После того как пользователь выделил нужную часть изображения, он жмет кнопку подтверждения формы, и данные о выделенной области передаются на сервер. А на сервере thumbnail уже вырезается из основной картинки по известным координатам и размерам прямоугольника.
А вот и сама функция вырезания изображения на php:
<? function img_crop($src, $dest, $x, $y, $width, $height, $rgb = 0xFFFFFF, $quality = 100) { if (!file_exists($src)) { return false; } $size = getimagesize($src); if ($size === false) { return false; } $format = strtolower(substr($size['mime'], strpos($size['mime'], '/') + 1)); $icfunc = 'imagecreatefrom'.$format; if (!function_exists($icfunc)) { return false; } $isrc = $icfunc($src); $idest = imagecreatetruecolor($width, $height); imagefill($idest, 0, 0, $rgb); imagecopyresampled($idest, $isrc, 0, 0, $x, $y, $width, $height, $width, $height); imagejpeg($idest, $dest, $quality); imagedestroy($isrc); imagedestroy($idest); return true; } ?>
Она очень похожа на предыдущую. В качестве параметров ей нужно передать:
- $src - имя исходной картинки
- $dest - имя картинки-результата,
- $x, $y - координаты левого верхнего угла прямоугольника, который будет вырезан из основной картинки,
- $width - ширина выделенной области,
- $height - и ее высота.
На этом все. Желаю успехов!
Cryptus.
Незнаю… лично мое мнение, что превьюшки делать вообще не стоит, изображение на сервер надо грузить как есть, а потом выводить через специальный скрипт, который его ресайзит и отображает. Конечно, будет нагрузка на сервер, но по сравнению с гибкостью метода это терпимо…
Спорный вопрос на самом деле. Объем кода в обоих случаях одинаковый получается примерно, и там и там можно кастыли поставить для подгона картинки
А где же функция для вырезания изображения по координатам?
Дописал ее в посте. Очень похожа на первую.
Спасибо, очень помогла статья, пошел встраивать!!!
# } elseif ($width == 0) {
#
# $x_ratio = $y_ratio;
# $width = $x_ration * $size[0];
Здесь ошибка, должна быть строка
# $width = $x_ratio * $size[0];
Спасибо, исправил.
Помните о том, что превьюшка на сервере практически ничего не весит, а создание её например из фотографии 2,2 МБ например на сервере может занять много ресурсов. Всякий раз нужно думать о гибкости сайта и о его способности к модернизации!!! Вдруг в последствии необходимо будет вывести штук 20 превьюшек…в пятницу вечерком например…сервак повешается такое делать - 100%
В демонстрации координаты выводятся в span id… как передать эти координаты серверу? я так понимаю, надо, чтобы координаты выводились в тег input… или я не прав? в любом случае вывести к input не получается ;( помогите!!
Кирилл, читайте статьи про jQuery. Вам нужно использовать AJAX.
Спасибо, стоящая статья!
А есть ли возможность с помощью php делать наложение картинок. Например у меня есть картинка1. Я хочу наложить на неё картинку2.
Да, есть такая возможность. Ищите в Интернете класс Watermark на PHP.
хорошо. А что насчет thumbnail -ов с видео. Есть скрипт такой?
Спасибо, очень помогло =) Особенно была нужна вторая функция, конечно не для создания превьюшек.
Спасибо за полезную статью! В особенности за наводку на jQuery. Делал некоторое время назад точь в точь тоже самое, но просто на javascript. ИЕ ессно как обычно зачудил, так и не отладил под него, плюнул нафиг. А тут почекал все четко работает