Достаточно нудно редактировать каждый раз изображения от руки да еще и в нескольких вариантах (мелкие - (90 на 90) и крупные (218 на сколько получится пикселей)). И тут же возникает проблема их хранения, а точнее пространства которое они занимают.
Обратившись к великому google ответ пришел сам...
Скрипт масштабирования resize.php
Входные параметры:
$f – имя файла в виде path/file.jpg.
$q – качество сжатия JPEG;
$type – формат картинки (в смысле линейные размеры) где в зависимости от значения $type производятся следующие действия:
$type = 0 – из исходной картинки вырезается квадратная серединка и приводится к формату 90x90 пикселей;
$type = 1 – исходная картинка масштабируется пропорционально и приводится к ширине 218 пикселей (опционально наносится надпись);
$type = 2 – исходная картинка выводится без изменений.
Начнем:
resize.php
<?php
// f - имя файла
// type - способ масштабирования
// q - качество сжатия
// src - исходное изображение
// dest - результирующее изображение
// w - ширниа изображения
// ratio - коэффициент пропорциональности
// str - текстовая строка
// тип преобразования, если не указаны размеры
if ($type == 0) $w = 70; // квадратная 70x70
if ($type == 1) $w = 90; // квадратная 90x90
if ($type == 2) $w = 218; // пропорциональная шириной 218
// качество jpeg по умолчанию
if (!isset($q)) $q = 100;
Здесь проверяются входные параметры. Смотрим дальше.
// создаём исходное изображение на основе
// исходного файла и опеределяем его размеры
$src = imagecreatefromjpeg($f);
$w_src = imagesx($src);
$h_src = imagesy($src);
header("Content-type: image/jpeg");
В этой части программы мы загружаем исходное изображение в переменную $src. Функции imagesx и imagesy определяют размеры исходной картинки и записывают их в соответствующие переменные. Они нам понадобятся для вычисления коэффициента пропорциональности. Здесь же с помощью функции header передаём заголовок Content-type: image/jpeg в браузер пользователя. После этого он ожидает, что следующий поток данных будет jpeg-файлом.
Следующее условие отвечает за размер выводимой картинки и непосредственно за вывод. Возможно, что исходная картинка уже нужного размера. Если это не так, обработаем её. Для этого поставим следующее условие:
// если размер исходного изображения
// отличается от требуемого размера
if ($w_src != $w)
{
Следующая часть программы будет подгонять картинку под ширину 218 пикселей (пропорциональное уменьшение) для случая $type=1.
// операции для получения прямоугольного файла
if ($type==2)
{
// вычисление пропорций
$ratio = $w_src/$w;
$w_dest = round($w_src/$ratio);
$h_dest = round($h_src/$ratio);
// создаём пустую картинку
// важно именно truecolor!, иначе будем иметь 8-битный результат
$dest = imagecreatetruecolor($w_dest,$h_dest);
$str = "foxweb.net.ru";
imagecopyresized($dest, $src, 0, 0, 0, 0, $w_dest, $h_dest, $w_src, $h_src);
Вначале вычисляем коэффициент $ratio, чтобы сразу вычислить размеры результирующей картинки $w_dest и $h_dest. Потом создаём новую картинку $dest с таким же размерами, это заготовка для масштабированной картинки. Самая сложная часть алгоритма – функция imagecopyresized. В ней я указал результирующую и исходную картинку, координаты левого верхнего угла для обоих картинок (0, 0, 0, 0) и координаты правого нижнего угла для обоих картинок ($w_dest, $h_dest, $w_src, $h_src). Вот официальная справка на эту функцию:
imagecopyresized - копирует и изменяет размеры части изображения
int imagecopyresized ( resource dst_im, resource src_im, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH)
imagecopyresized() копирует прямоугольную часть одного изображения в другое изображение. Dst_im - результирующее изображение, src_im - исходное изображение. Если исходные и координаты расположения и ширины и высот отличаются, будет выполнено растяжение или сжатие фрагмента изображения. Начало координат - верхний левый угол. Эта функция может быть использована, чтобы копировать области в пределах того же изображения (если dst_im и src_im совпадают), но если области перекрывают результаты быть непредсказуемым.
Вместо неё можно использовать imagecopyresampled() - ресемплирование со сглаживанием. Картинка получится более качественной. Подробнее о параметрах функции можно узнать в документации на сайте http://php.net/imagecopyresized/ .
Следующая часть кода совершенно необязательна. Она печатает произвольную надпись на готовой картинке. Причём, контрастным цветом: на тёмном фоне надпись будет белая, на светлом – чёрная. Сначала определим координаты вывода текста (в нашем примере это внизу справа) и три цвета – $white, $black и $gray с помощью функции imagecolorallocate. Чтобы определить, каким цветом печатать надпись, сравним цвет точки (функция imagecolorat), где будет надпись, со «средним» цветом $gray. Если цвет точки окажется светлее серого, то надпись будет чёрного цвета ($color = $black). Если цвет точки окажется темнее серого, то надпись будет белого цвета ($color = $white). Наконец определяем строку $str и наносим её функцией imagestring, указав размер шрифта, координаты, строку и цвет. Помните, что эта функция выводит только латинские символы одним шрифтом. Хотя никто не запрещает вам пользоваться TrueType шрифтами, благо такие функции есть.
// определяем координаты вывода текста
$size = 2; // размер шрифта
$x_text = $w_dest-imagefontwidth($size)*strlen($str)-3;
$y_text = $h_dest-imagefontheight($size)-3;
// определяем каким цветом на каком фоне выводить текст
$white = imagecolorallocate($dest, 255, 255, 255);
$black = imagecolorallocate($dest, 0, 0, 0);
$gray = imagecolorallocate($dest, 127, 127, 127);
if (imagecolorat($dest,$x_text,$y_text)>$gray) $color = $black;
if (imagecolorat($dest,$x_text,$y_text)<$gray) $color = $white;
// выводим текст
imagestring($dest, $size, $x_text-1, $y_text-1, $str,$white-$color);
imagestring($dest, $size, $x_text+1, $y_text+1, $str,$white-$color);
imagestring($dest, $size, $x_text+1, $y_text-1, $str,$white-$color);
imagestring($dest, $size, $x_text-1, $y_text+1, $str,$white-$color);
imagestring($dest, $size, $x_text-1, $y_text, $str,$white-$color);
imagestring($dest, $size, $x_text+1, $y_text, $str,$white-$color);
imagestring($dest, $size, $x_text, $y_text-1, $str,$white-$color);
imagestring($dest, $size, $x_text, $y_text+1, $str,$white-$color);
imagestring($dest, $size, $x_text, $y_text, $str,$color);
}
Несколько сложнее выглядит часть кода для получения квадратного фрагмента.
// операции для получения квадратного файла
if (($type==0)
($type==1))
{
// создаём пустую квадратную картинку
// важно именно truecolor!, иначе будем иметь 8-битный результат
$dest = imagecreatetruecolor($w,$w);
// вырезаем квадратную серединку по x, если фото горизонтальное
if ($w_src>$h_src)
imagecopyresized($dest, $src, 0, 0,
round((max($w_src,$h_src)-min($w_src,$h_src))/2),
0, $w, $w, min($w_src,$h_src), min($w_src,$h_src));
// вырезаем квадратную верхушку по y,
// если фото вертикальное (хотя можно тоже серединку)
if ($w_src<$h_src)
imagecopyresized($dest, $src, 0, 0, 0, 0, $w, $w,
min($w_src,$h_src), min($w_src,$h_src));
// квадратная картинка масштабируется без вырезок
if ($w_src==$h_src)
imagecopyresized($dest, $src, 0, 0, 0, 0, $w, $w, $w_src, $w_src);
}
// вывод картинки и очистка памяти
imagejpeg($dest,'',$q);
imagedestroy($dest);
imagedestroy($src);
}
Мы не определяем коэффициент масштабирования, поскольку картинка будет квадратной заранее известного размера. По размеру картинка может быть трёх типов – горизонтальная, вертикальная и квадратная. В первых двух случаях нам придётся вырезать и масштабировать квадратную область из прямоугольной картинки. В третьем – просто масштабировать.
Обычно в горизонтальных картинках (лица, пейзажи, объекты) наиболее информативна центральная часть, а в вертикальных (чаще всего это стоящие люди) - наиболее важна верхняя часть. Чтобы изменить вырезаемый фрагмент вертикальной картинке, строку:
imagecopyresized($dest, $src, 0, 0, 0, 0, $w,
$w, min($w_src,$h_src), min($w_src,$h_src));
можно заменить на
imagecopyresized($dest, $src, 0, 0, 0,
round((max($w_src,$h_src)-min($w_src,$h_src))/2),
$w, $w, min($w_src,$h_src), min($w_src,$h_src));
Тогда в вертикальной картинке будет браться не верхняя часть, а средняя (это зависит от расположения объектов на фотографии). Точно так же можно брать нижнюю часть или правую/левую часть горизонтальной картинки – поэкспериментируйте с координатами. Особенно этот метод пригодится, если нужно создать квадратные «превьюшки» (thumbnails) в одной таблице.
В конце выводим картинку imagejpeg() и очищаем память imagedestroy().
Почему не работает?
Отлаживаем скрипты в Windows, поэтому объясню решение проблемы именно для этой ОС. Скорее всего, причина неработоспособности скрипта в отсутствии модуля php_gd.dll (или более новый php_gd2.dll). Откройте директорию с интерпретатором PHP, создайте директорию extensions, если её нет. Найдите вышеуказанный модуль – он есть в полных дистрибутивах PHP. Пропишите в php. ini (лежит в c:\ windows) строчку extension = php_gd2.dll (а заодно и extension_dir = "c:\php\extensions\", если такой нет). Пути могут быть другими. После этого всё должно заработать. Не «смешивайте» модули php_gd.dll и php_gd2.dll – интерпретатор будет ругаться на дублирование функций в библиотеках.
И на последок...
Вот что можно сделать при помощи графических функций – зато какая экономия на изготовлении и хранении дублирующих картинок. Не PhotoShop конечно, но для массового применения это самое оно.
Комментариев нет:
Отправить комментарий