Ключевые слова:php, db, image, graph, (найти похожие документы)
From: Denis Roshchin <denis@komkon.org.>
Date: Mon, 20 Sep 2004 18:21:07 +0000 (UTC)
Subject: Работа с изображениями на PHP используя библиотеку GD.
Оригинал: http://www.komkon.org:8008/~denis/mydoc/gd.htm
PHP/GD. Работа с изображениями. Основные функции, примеры
Denis Roshchin, <denis@komkon.org.>, http://www.komkon.org/~denis/
...и жалко и радостно, что не видят
исходных кодов пользователи...
...и плакать хочется, и радуешься,
что не узрят они твои велосипеды...
...и никто не узнает что же там на
самом деле...внутри...
...что не использовали мы стандартные
функции, а что живем мы правильно,
по-доброму...
...что все у нас хоть и криво, но родно...
Предисловие.
Несколько слов о GD
GD - библиотека, используемая для работы с двухмерной графикой. На
данный момент, в связи с проблемами авторского права начиная с GD
версии 1.6 - полностью удалена поддержка GIF, которую заменили
аналогичными функциями PNG (Однако же никто не мешает найти более
старую версию, которая несмотря не на что лежит на многих серверах).
PNG - новый формат-альтернатива формату GIF, специально разработанный
для передачи изображений через интернет, обеспечивающий большую
степень сжатия и лучшее качество. Данный формат поддерживается
ведущими браузерами - IE, Netscape и Opera.
Скачать модуль GD можно по адресу http://www.boutell.com/gd/
Чтобы проверить, что GD поддерживается в системе, попробуйте:
if(function_exists('imagetypes'))
echo 'GD is loaded';
else
echo 'GD is not loaded';
Я заметил, что множество народу ищут старые дистрибутивы GD, которые
еще поддерживают формат GIF. Хочу еще раз отметить, что это не всегда
обосновано, так как: (1) формат PNG поддерживается всеми новыми
браузерами и (2) одно и тоже изображение в GIF и PNG - в последнем
смотрится лучше, а места занимает меньше.
Где я могу использовать GD
Большое поле применения GD - интернет программирование. На самом деле
область применения GD в интернете намного выше, чем может показаться
на первый взгляд. Более подробно о возможности его применения смотрите
раздел примеры этой и последующих частей статьи.
Часть 1. Основные функции.
Черный квадрат...
Используя GD можно как создавать свои новые изображения, так и
загружать имеющиеся и модифицировать их (или нет - если, по какой-то
причине не хотите, чтобы пользователи видели что где у вас лежит :)).
Ниже описаны основные функции пакета GD:
* int ImageCreate(int x, int y)
Функция создает новое изображение размером x на y. Возвращает
идентификатор - номер картинки, который необходимо использовать как
ссылку при вызовах других функций.
* ImageDestroy(int image)
Уничтожает изображение тем самым, освободив связанные с ним ресурсы.
Этой функцией необходимо пользоваться после сохранения изображения или
отправки его в браузер.
Единственный параметр - ссылка.
* int ImageCreateFromGif(str filename)
Импортирует изображение из файла .gif и возвращает его идентификатор.
Единственный параметр - имя файла, импорт которого необходимо
совершить. В случае неудачи функция возвращает значение ФАЛСЕ.
* ImageGif(int image, string filename)
Позволяет сохранить объект-изображение в файле. Если параметр filename
опущен, то файл выводится непосредственно в поток данных.
Рассмотрим, как пример, маленький код, который открывает файл и
сохраняет его под новым именем:
<?php
$image = @ImageCreateFromGIF("images/picture01.gif");
if($image==" "){print "ERR"; exit();}
//Здесь возможно вставить код, изменяющий изображение
ImageGif($image,"p01.gif");
ImageDestroy($image);
?>
* ImageCopyResized
Функция позволяет делать копию изображения, или его прямоугольной
части, изменяя его размер. Синтаксис:
int ImageCopyResized(int new_image, int old_image, int newX, int newY,
int oldX, int oldY, int newW, int newH, int oldW, int oldH)
* ImageLine, ImageDashedLine (int image, int x1, int y1, int x2, int y2, int color)
Функции, вычерчивающие прямую линию между двумя точками. ImageLine -
прямую линию; ImageDashedLine - заштрихованную. Параметры функции -
точка начала линии, точка конца линии, цвет и идентификатор
изображения. Как всегда, левый верхний угол имеет значение x-y -
(0,0).
* ImageRectangle, ImageFilledRectangle
* ImagePolygon, ImageFilledPolygon
Я не буду очень подробно останавливаться на описании этой функции, так
как сомневаюсь в необходимости их постоянного использования обычным
программистом.
Данные функции рисуют прямоугольник (функции *Rectangle) или
непрямоугольные фигуры (функции Polygon). Синтаксис:
int Image(Filled)Rectangle(int im, int x1, int y1, int x2, int y2, int col);
int Image(Filled)Polygon(int im, array points, int num_points, int col);
* ImageFill, ImageFillToBorder
Функции делают заливку цветом color всей области вокруг указанной
точки имеющий такой же цвет, как и она сама. Вторая функция отличается
от первой наличием контура. Синтаксис функций:
int ImageFill(int image, int x, int y, int color);
int ImageFillToBorder(int image, int x, int y, int border_color, int color);
Некоторые основные функции работы с цветом
* int ImageColorAllocate(int image, int red, int green, int blue)
Одна из самых важных функций для работы с цветом. Используется для
назначения цветов изображениям. В функцию передаются три значения трех
цветов (красный, зеленый, синий) в диапазоне от нуля до 255.
Например:
$white = ImageColorAllocate($image, 255, 255, 255);
$black = ImageColorAllocate($image, 0, 0, 0);
Первые два вызова этой функции после ImageCreate задают цвет фона и
цвет вычерчивания.
* int ImageColorAt(int image, int x, int y)
Возвращает цвет точки (x,y) в изображении image.
* bool ImageColorSet(int image, int index, int red, int green, int blue)
Заменяет во всем изображении один цвет другим.
* int ImageColorTransparent(int image, int color)
Позволяет заменить во всем изображении какой-либо цвет прозрачностью.
Определяет цвет прозрачным.
* imagecolortransparent() устанавливает прозрачным цвет в изображении
image вместо цвета color. image - идентификатор изображения,
возвращаемый функцией imagecreate() и color - идентификатор цвета,
возвращаемый функцией imagecolorallocate().
Прозрачный цвет - свойство изображения! Это не свойство самого цвета.
Однажды выбрав, что цвет color будет заменен прозрачным цветом, - все
места изображения этого цвета будут прозрачными.
Функция возвращает идентификатор нового прозрачного цвета (или
текущего, если не указано).
После того (или до этого), как какой то цвет (color) определен как
прозрачный, при использовании этого цвета любой другой функции - цвет
будет прозрачным.
Пример:
$red = ImageColorAllocate ($im, 233, 14, 91);
$blue = ImageColorAllocate ($im, 0x20, 0x60, 0xaa);
imagefilledarc ($im, 100, 100, 80, 80, 0, 60, $blue, IMG_ARC_PIE);
//arc - прозрачный, даже если он еще пока не определен
$trans=imagecolortransparent($im,$blue);
//изменяет все blue, до, или после, этого оператора
После этого, чтобы вывести прозрачный текст, можно воспользоваться
любым из следующих двух вариантов (они полностью эквивалентны):
ImageString ($im, 10, 5, 5, "Transparent Text String", $blue);
ImageString ($im, 10, 5, 5, "Transparent Text String", $trans);
Работа с размерами
* Функция getimagesize().
Синтаксис:
array getimagesize ( string filename [, array imageinfo])
Функция getimagesize() определяет размер любого изображения GIF, JPG, PNG, SWF,
SWC, PSD, TIFF, BMP или IFF.
Хорошая практика - использование результатов данной функции на динамических стр
аницах внутри IMG тэга.
Функция возвращает массив состоящий из четырех элементов. Индекс 0
содержит ширину изображения в пикселях. Индекс 1 - высоту. Индекс 2 -
индикатор типа изображения: 1 = GIF, 2 = JPG, 3 = PNG, 4 = SWF, 5 =
PSD, 6 = BMP, 7 = TIFF(intel byte order), 8 = TIFF(motorola byte
order), 9 = JPC, 10 = JP2, 11 = JPX, 12 = JB2, 13 = SWC, 14 = IFF.
Индекс 3 - корректная строка height="yyy" width="xxx" которая может
быть использована непосредственно в IMG тэге.
Функции ImageSX, ImageSY (аналогичные getimagesize) возвращают лишь
один размер - ширину или высоту соответственно.
Все три функции имеют лишь один параметр - ссылку на изображение.
Пример (из файла):
<?php
$size = getimagesize ("img/flag.jpg");
echo "<img src=\"img/flag.jpg\" {$size[3]}>";
?>
Пример (с URL):
<?php $size = getimagesize ("http://www.example.com/gifs/logo.gif");
?>
Для изображений JPG, или всех типов, начиная с PHP 4.3, возвращается
также два дополнительных элемента в массиве: канал(3=RGB,4=CMYK) и
битность(количество для каждого цвета).
В некоторых случаях (для некоторых форматов), когда функция
getimagesize() не может определить размеры изображения, возвращаются
два нуля вместо значений ширины и высоты.
Пример. Изменение размера изображения
Одна из наиболее часто встречающихся задач - изменение размера
картинки (например, при создании фотоальбома с предпросмотром).
Improved version of ResizeGif given by tjhunter with Height % Widht.
/* ResizeGif with (height % width) */
function RatioResizeImg( $image, $newWidth, $newHeight){
// открываем gif-файл
eregi(".(.*)$",$image,$regs);
switch($regs[1]){
case "gif": $srcImage = ImageCreateFromGIF( $image ); break;
case "jpg": $srcImage = ImageCreateFromJPEG( $image ); break;
case "png": $srcImage = ImageCreateFromPNG( $image ); break;
default: $srcImage = ImageCreateFromGIF( $image ); break;
}
// определяем изначальную высоту и ширину картинки
$srcWidth = ImageSX( $srcImage );
$srcHeight = ImageSY( $srcImage );
// следующий код проверяет если ширина больше высоты
// или высота больше ширины картинки так, чтобы
// при изменении сохранилась правильная пропорция
$ratioWidth = $srcWidth/$newWidth;
$ratioHeight = $srcHeight/$newHeight;
if( $ratioWidth < $ratioHeight){
$destWidth = $srcWidth/$ratioHeight;
$destHeight = $newHeight;
}else{
$destWidth = $newWidth;
$destHeight = $srcHeight/$ratioWidth;
}
// создаем новую картинку с конечными данными ширины и высоты
$destImage = imagecreate( $destWidth, $destHeight);
// копируем srcImage (исходная) в destImage (конечную)
ImageCopyResized( $destImage, $srcImage, 0, 0, 0, 0, $destWidth,
$destHeight, $srcWidth, $srcHeight );
//создаем gif
ImageGif( $destImage );
// освобаждаем память
ImageDestroy( $srcImage );
ImageDestroy( $destImage );
}
// сохраняем вывод в буфер
ob_start();
// изменяем размер; будет сохранено в буфере
ResizeGif( "/where/image/is/image.gif", "150", "150");
// копируем в переменную
$resizedImage = ob_get_contents();
// очищаем буфер
ob_end_clean();
// сохраняем $resizedImage в базу данных, файл, выводим ее в
браузер...
?>
Получение размера изображения GIF без использования GD
Зная формат GIF, возможно получить размеры изображения без
использования GD и не подгружая весь файл:
function GetGifSize($filename, &$width, &$height)
{
DEFINE('GIFBUFSIZE', 10);
@set_magic_quotes_runtime(0);
$fd = fopen($filename, 'rb');
$a = fread($fd, GIFBUFSIZE);
fclose($fd);
@set_magic_quotes_runtime(get_magic_quotes_gpc());
if ((ord($a[0]) == 0x47) && (ord($a[1]) == 0x49) && (ord($a[2]) == 0x46)) // 'GIF'
{
$width = ord($a[7]) * 256 + ord($a[6]);
$height = ord($a[9]) * 256 + ord($a[8]);
return true;
}
else
return false;
}
Кэширование
Очень часто, например при построении систем меню на сайте, сохраняют
картинки в кэше и не всегда когда необходимо перегружают их.
Решение этой проблемы - указывать в заголовках директивы управления
кэшем.
Пример:
Header ("Last-Modified: " . gmdate("D, d M Y H:i:s",mktime (0,0,0,1,1,2000)) . " GMT");
// Дата в прошлом
Header ("Expires: Mon, 26 Jul 2040 05:00:00 GMT");
// Дата истечения актуальности. В данном случае картинка всегда актуальна.
Header ("Cache-Control: max-age=10000000, s-maxage=1000000, proxy-revalidate, must-revalidate");
//Cache-Control сообщает браузеру (как и прокси-серверу) перезагрузить
// все картинки! В данном случае после 1 миллиона секунд.
Функция read_exif_data
Она же exif_read_data().
Читает информацию из заголовка TIFF или JPEG изображения.
Cинтаксис:
array exif_read_data ( string filename, string sections, bool arrays, bool thumbnail)
Так как read_exif_data() читает файл целиком, и если каждый файл по
размеру больше мегабайта, это слишком медленно, можно воспользоваться
нижеследующей функцией, которая читает лишь начало каждого файла:
function read_exif_data_quick($path) {
$tmpfile = "/tmp/read_exif_data_quick.tmp_file";
$in = fopen($path, "r");
$out = fopen($tmpfile,"w");
fwrite( $out, fread( $in, 15000 ) );
fclose($in);
fclose($out);
return read_exif_data($tmpfile);
}
Поворот изображения
В библиотеке GD нет функции, которая бы поворачивала картинку под
определенным углом. Однако велосипед поехал...
<?php
function imagerotate(&$img, $ang, $bg=FALSE, $width=FALSE,
$height=FALSE, $bench=FALSE) {
if($bench) $time = microtime();
if(!$bg) $bg = imagecolorallocate($img, 255,255,255);
// size of the image
$src_w = imagesx($img);
$src_h = imagesy($img);
// reduce angle
while($ang > 180) $ang = $ang-360;
while($ang < -180) $ang = $ang+360;
// угол > 90°
if($ang > 90) {
imagerotate($img, 90, $bg, $src_h,$src_w);
$ang = $ang - 90;
}
elseif($ang < -90) {
imagerotate($img, -90, $bg, $src_h,$src_w);
$ang = $ang + 90;
}
// размер изображения
$src_w = imagesx($img);
$src_h = imagesy($img);
if($ang != 0) {
// перевод градусов в радианы
if($ang > 0) $wrad = deg2rad($ang);
else $wrad = deg2rad((-1*$ang));
$sin = sin($wrad); if($sin < 0) $sin*=-1;
$cos = cos($wrad); if($cos < 0) $cos*=-1;
// размер изображения, после поворота
$dst_w = (int) ( $sin*$src_h + $cos*$src_w );
$dst_h = (int) ( $cos*$src_h + $sin*$src_w );
if($dst_w < 0) $dst_w *= -1;
if($dst_h < 0) $dst_h *= -1;
$scale_x = (int) ( $width/$dst_w );
$scale_y = (int) ( $height/$dst_h );
// создаем изображение и устанавливаем цвет фона
$dst_img = imagecreatetruecolor($dst_w, $dst_h);
imagefill($dst_img, 0,0, $bg);
for($i=0; $i<$src_h; $i++) {
for($j=0; $j<$src_w; $j++) {
// получаем новую позицию пикселя
if($ang > 0) {
$dst_x = (int) ( $sin*($src_h-$i) + $cos*$j );
$dst_y = (int) ( $sin*$j + $cos*$i );
}
else {
$dst_x = (int) ( $sin*$i + $cos*$j );
$dst_y = (int) ( $sin*($src_w-$j) + $cos*$i );
}
if($scale_x != 0) $dst_x = $dst_x*$scale_x;
if($scale_y != 0) $dst_y = $dst_y*$scale_y;
// получаем цвет данного пикселя
$col = imagecolorat($img, $j, $i);
// рисуем пиксель (рисуем два пикселя за раз чтобы избежать появления
// брешей/окон)
imagefilledrectangle($dst_img, $dst_x,$dst_y, $dst_x+1,$dst_y, $col);
}
}
// необходимо взять пробу
if($width!==FALSE && $height!==FALSE && ($width!=$dst_w || $height!=$dst_h)) {
$new_img = imagecreatetruecolor($width, $height);
imagefill($new_img, 0,0, $bg);
imagecopyresampled($new_img, $dst_img, 0,0,0,0, $width,$height,
$dst_w,$dst_h);
imagedestroy($dst_img);
$img = $new_img;
}
else $img = $dst_img;
}
// не надо поворачивать, только взять пробу
elseif($width!==FALSE && $height!==FALSE && ($width!=$dst_w || $height!=$dst_h)) {
$dst_img = imagecreatetruecolor($width, $height);
imagefill($dst_img, 0,0, $bg);
imagecopyresampled($dst_img, $img, 0,0,0,0, $width, $height, $src_w, $src_h);
$img = $dst_img;
}
// ничего не надо делать
else $img = $dst_img;
if(!$bench) return;
// необязательная часть модуля, которая выводит данные работы функции
elseif($bench == "IMAGE") {
list($usec, $sec) = explode(" ",microtime());
$etime = (float)$usec + (float)$sec;
list($usec, $sec) = explode(" ",$time);
$etime -= (float)$usec + (float)$sec;
$etime = substr($etime, 0, 7);
imagefilledrectangle($img, 0,0, 42,12, imagecolorallocate($img, 255,255,255));
imagestring($img, 2, 0,0, $etime, imagecolorallocate($img, 0,0,0));
}
elseif($bench == "STRING") {
list($usec, $sec) = explode(" ",microtime());
$etime = (float)$usec + (float)$sec;
list($usec, $sec) = explode(" ",$time);
$etime -= (float)$usec + (float)$sec;
return $etime;
}
}
?>
Итак, функция imagerotate. Синтаксис:
imagerotate($img, $ang[, $bg[, $width, $height[, $bench]]]);
$img - изображение, которое необходимо вращать.
$ang - угол поворота
$bg (опционально) - индекс цвета фона (по-умолчанию: белый)
$width и $height (опционально) - изображение будет приведено к этому
размеру. Обязательно использование обоих параметров вместе!
$bench (опционально)
"STRING" возвращает время, необходимое для выполнить функцию.
"IMAGE" поместит маленькую отметку с временем на изображение.
Примерное время выполнения функции при изображении размером 250x200px
при повороте <90° составляет примерно 1 секунду; при повороте на
угол >90° - ~2 секунды
!Эта функция работает только с изображениями JPEG!
Работа с текстом
Поместить текст на изображение можно используя одну из функций работы
с текстом.
* Функция imagestring().
Выводит строку текста.
Синтаксис:
int imagestring ( resource image, int font, int x, int y, string s, int col)
Функция выводит строку текста горизонтально в заданном изображении
image цветом col в координатах x, y (верхний левый угол соответствует
0, 0). Если значение шрифта указано 1, 2, 3, 4 или 5 - используются
встроенный шрифт (увеличение значения - больше по размеру шрифт).
* Функция imagestringup().
Выводит строку текста вертикально.
Синтаксис:
int imagestringup ( resource image, int font, int x, int y, string s, int col)
Аналогичная функции imagestring(). Выводит текст вертикально.
* Функция imagettftext().
Пишет текст на изображение используя шрифты TrueType.
Синтаксис:
array imagettftext ( resource image, int size, int angle, int x, int y,
int col, string fontfile, string text)
Функция пишет text на изображение image, начиная в координатах x, y
(верхний левый угол - 0, 0), под углом angle цеветом col, используя
шрифт TrueType fontfile. В зависимости от версии, если отсутствуют '/'
и '.ttf', то будет произведена попытка поиска шрифта в стандартной
папке шрифтов.
Координаты, заданные x и y, определяют базовую точку первого символа.
В отличии от функции imagestring(), где координаты определяют верхний
правый угол первой буквы, координаты указывают на левый верхний угол
первого символа.
Angle - угол в градусах. Значение 0 выведет текст справа налево;
повышение значения определяет отклонение против часовой стрелки. Таким
образом, значение 90, на выводе даст текст написанный снизу вверх.
Fontfile - путь к шрифту TrueType желаемый к использованию.
Text - текст; может включать в себя UTF-8 символы.
Функция imagettftext() возвращает массив из восьми эллементов. В нем
соответственно расположены следующие точки обрамляющие края текста:
нижний левый, нижний правый, верхний правый, верхний левый.
Точки находятся в соответствии с углом и относительно текста, т.е.
если текст расположен вертикально (снизу вверх), то <<правым верхним
углом>> на практике будет являться точка находящаяся слева вверху над
текстом.
Следующий пример создает черный GIF 400x30 пикселей, со словами
"Testing..." белым цветом и шрифтом Arial (этой функции необходима как
библиотека GD, так и FreeType библиотека).
<?php
header ("Content-type: image/gif");
$im = imagecreate (400, 30);
$black = imagecolorallocate ($im, 0, 0, 0);
$white = imagecolorallocate ($im, 255, 255, 255);
imagettftext ($im, 20, 0, 10, 20, $white, "/path/arial.ttf", "Testing...Omega:Ω");
imagegif ($im);
imagedestroy ($im);
?>
Пример:
// создаем изображение
$gif = ImageCreate(200,200);
$bg = ImageColorAllocate($gif,0,0,0);
$tx = ImageColorAllocate($gif,255,128,128);
ImageFilledRectangle($gif,0,0,200,200,$bg);
// помещаем строку на него
ImageString($gif,3,70,90,"it works !",$tx);
// посылаем изображение
header("content-type: image/gif");
ImageGif($gif);
Пример:
Вставка строки Copyright в каждую фотографию в фотоальбоме посредствам PHP/GD
Еще один из наиболее частых случаев использования PHP/GD, как мне
кажется, - вставка авторской информации при выводе изображений.
Например, "Vasya (c) 2003". Такой скрипт в фотоальбоме - удобная вещь.
Каждый видит свои преимущества, а если поразмышлять еще, то находятся
и другие, о которых кто-то еще уже подумал :-).
Итак, алгоритм программы:
1. Загрузить готовую фотографию в объект.
2. Найти точки на рисунке где должна быть надпись. Надпись по длине,
по моим расчетам, примерно 130 и 12 пикселей по высоте.
3. Вставить надпись.
4. Передать фотографию на выход.
<?php
function ImageLoad($ImageToLoad){
$image = @ImageCreateFromGIF($ImageToLoad);
if($image==" ") {
#Случай неудачи открытия сообщения
#Используем заранее приготовленный файл с
#картинкой-изображением ошибки скрипта.
$err = ImageCreateFromGif("error.gif");
return $err;
} else {
return $image;
}
}
header("Content-Type: image/gif");
$str = "Vasya P. (C) 2003";
if(!isset($ImageToLoad)){
#Проверим, что переменная передана
print "No picture is selected";
exit();
}
$image=ImageLoad($ImageToLoad);
#Найдем X и Y где надо будет расположить надпись.
$X_var = ImageSX($image); $X_var = $X_var - 130; #shirina
$Y_var = ImageSY($image); $Y_var = $Y_var - 12; #visota
#Определим некоторые цвета
$black = ImageColorAllocate($image, 0, 0, 0);
$white = ImageColorAllocate($image, 255, 255, 255);
#Добавляем строку
ImageString($image,5,$X_var,$Y_var,$str,$white);
#Вывести изображение, затем уничтожив его
ImageGif($image);
ImageDestroy($image);
?>
Часть 2. Некоторые дополнительные функции GD/PHP.
* Функции imagechar() и imagecharup().
Выводят на изображение символ горизонтально и вертикально
соответственно.
Синтаксис:
int imagechar ( resource image, int font, int x, int y, string c, int col)
int imagecharup ( resource image, int font, int x, int y, string c, int col)
* Функция imagecolorclosest().
Возвращает индекс ближайшего цвета к указанному.
Синтаксис:
int imagecolorclosest ( resource image, int red, int green, int blue)
Возвращает индекс цвета ближайшего к указанному цвету формата RGB.
Эту функцию иногда необходимо использовать в работе с изображениями
JPEG в случае, если происходит эффект <<водных знаков>> на изображении
при использовании цвета.
* Функция imagecolorstotal().
Возвращает количество цветов, из палитры данного изображения.
Синтаксис:
int imagecolorstotal ( resource image)
Функция не всегда корректно работает с изображениями jpeg; также в
текущей версии функция не имеет возможность правильно определять
количество цветов в изображении где их более 256.
Функция 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)
Функция копирует прямоугольную область изображения на другое
изображение.
Dst_im - изображение назначени; src_im - источник.
Координаты соответствуют левому верхнему углу. Функция позволяет быть
использованной для копирования части изображения внутри себя (если
dst_im совпадает с src_im), но если изображения будут перекрываться -
результат может быть непредсказуемым.
* Функция imagecopymerge().
Копирует часть изображения и совмещает его с другим.
Синтаксис:
int imagecopymerge ( resource dst_im, resource src_im, int dst_x, int
dst_y, int src_x, int src_y, int src_w, int src_h, int pct)
Копируется часть src_im на dst_im начиная в координатах x,y - src_x,
src_y и dst_x, dst_y - соответственно исходного изображения и точек
второго изображения, на которое производится копирование. Размеры
прямоугольника, подлежащего копированию, определяются шириной и
высотой src_w и src_h.
Два изображение будут совмещены с интенсивностью определенной в pct,
которая имеет область от 0 до 100. При pct = 0, ничего не происходит;
При 100, данная функция действует идентично imagecopy().
* Функция imagecopymergegray().
Аналогичная предыдущей функция по синтаксису и работе. Исключение -
перед тем, как скопировать изображение, заменяет зону на которую будет
произведено копирование серым цветом.
* Функция iptcembed().
Позволяет работать с бинарной информацией IPTC в JPEG файлах.
Синтаксис:
array iptcembed ( string iptcdata, string jpeg_file_name [, int spool])
Используется вместе с функцией iptcparse(), которая позволяет
разбирать iptc-результаты.
Синтаксис: array iptcparse ( string iptcblock)
Возвращает FALSE если не было найдено iptc-текста.
Если вы не уверены куда конкретно поместился текст, введенный с
помощью графического пакета, например, можно просто просмотреть весь
блок.
$size = GetImageSize ("testimg.jpg", &$info);
$iptc = iptcparse($info["APP13"]);
foreach($iptc as $key => $value)
{
echo "<b>IPTC Key:</b> $key <b>Contents:</b> ";
foreach($value as $innerkey => $innervalue)
{
if( ($innerkey+1) != count($value) )
echo "$innervalue, ";
else
echo "$innervalue";
}
}
Пример.
Очень удобно, например, хранить информацию о фотографиях в фотоальбоме
непосредственно в файле с изображением.
$size = GetImageSize ("$image_name",&$info);
$iptc = iptcparse ($info["APP13"]);
if (isset($info["APP13"])) {
$iptc = iptcparse($info["APP13"]){
if (is_array($iptc)) {
$caption = $iptc["2#120"][0];
$graphic_name = $iptc["2#005"][0];
$urgency = $iptc["2#010"][0];
$category = $iptc["2#015"][0];
$supp_categories = $iptc["2#020"][0];
$spec_instr = $iptc["2#040"][0];
$creation_date = $iptc["2#055"][0];
$photog = $iptc["2#080"][0];
$credit_byline_title = $iptc["2#085"][0];
$city = $iptc["2#090"][0];
$state = $iptc["2#095"][0];
$country = $iptc["2#101"][0];
$otr = $iptc["2#103"][0];
$headline = $iptc["2#105"][0];
$source = $iptc["2#110"][0];
$photo_source = $iptc["2#115"][0];
$caption = $iptc["2#120"][0];
}
}
Пример.
При работе в системе необходимо понимать, что есть различие между
текстовыми и бинарными файлами. Так что если запускать нижележащий
пример на платформе Windows, изображение будет искажено. Добиться
правильной работы можно, поместив на открытие файла (функция fopen())
- 'wb', вместо 'w'.
Данный пример читает IPTC текст из изображение, изменяет его и
записывает в новый файл. Используемые функции - iptcparse() и
iptcembed().
<?
// имя исходного файла
$image_name_old = "test.jpg";
// имя нового файла
$image_name_new = "test2.jpg";
// Читаем IPTC-текст в массив '$iptc'
// Номер следующий за '#' - поле IPTC
// Например: $iptc["2#090"][0] - поле Город.
// $iptc["2#055"][0] - дата создания
$size = GetImageSize ("$image_name_old",&$info);
$iptc_old = iptcparse ($info["APP13"]);
// Добавление или замена текста IPTC.
// В этом примере заменяется оригинальная категория
// или создается, если не существует
$iptc_old["2#015"][0] = "Sport";
// .. и добавляем еще текст к заголовку (Caption)
$iptc_old["2#120"][0] .= " More caption text";
// Создаем новую строку IPTC
foreach (array_keys($iptc_old) as $s){
// Находим номера IPTC
$tag = str_replace("2#", "", $s);
// Создаем строку
$c = count ($iptc_old[$s]);
for ($i=0; $i <$c; $i++)
{
$iptc_new .= iptc_maketag(2, $tag, $iptc_old[$s][$i]);
}
}
// Исходный файл и новые две строки записываем в $content
// Mode 0 - сохраняет изображение в $content
// Mode 1 - сохраняет в $content и посылает браузеру
// Mode 2 - посылает браузеру
$mode = 0;
$content = iptcembed($iptc_new, $image_name_old, $mode);
// пишем в новый файл
$fp = fopen($image_name_new, "w");
fwrite($fp, $content);
fclose($fp);
// Функция форматирование нового текста IPTC.
function iptc_maketag($rec,$dat,$val){
$len = strlen($val);
if ($len < 0x8000)
return chr(0x1c).chr($rec).chr($dat).chr($len >> 8).
chr($len & 0xff).$val;
else
return chr(0x1c).chr($rec).chr($dat).chr(0x80).chr(0x04).
chr(($len >> 24) & 0xff).chr(($len >> 16) & 0xff).
chr(($len >> 8 ) & 0xff).chr(($len ) & 0xff).$val;
}
?>
Наиболее часто используемые поля IPTC.
005 - Object Name (Имя объекта)
007 - Edit Status
010 - Priority (Приоритет)
015 - Category (Категория)
020 - Supplemental Category
022 - Fixture Identifier
025 - Keywords (Ключевые слова)
030 - Release Date
035 - Release Time
040 - Special Instructions (Специальные инструкции)
045 - Reference Service
047 - Reference Date
050 - Reference Number
055 - Created Date (Дата создания)
060 - Created Time (Время создания
065 - Originating Program
070 - Program Version
075 - Object Cycle
080 - Byline
085 - Byline Title
090 - City (Город)
095 - Province State
100 - Country Code (Код страны)
101 - Country (Страна)
103 - Original Transmission Reference
105 - Headline
110 - Credit
115 - Source
116 - Copyright String (Авторская информация)
120 - Caption
121 - Local Caption
Информация взята из открытых источников,
Документации по библиотеке GD, а также
Из конференций и форумов по PHP и GD.
Функция поворота картинки под углом: Дженс Готтфрид.
Помощь в создании функции работы с IPTC-текстом: Тиес Арнтзен.
Денис Рощин, 2002.
Всё неплохо написано. Но опять таки никаких подробностей по выводу изображений в браузер. Уже неделю тыкаюсь, выводится максимум первая миниатюра из длинного списка, или все, но в текстовой кодировке.
>Keij, перед выводом нужно послать заголовок с типом контента:
>header('Content-type: image/jpeg');
>(если это JPEG)
Да разобрался... Хедер тут непричём, просто один сценарий впринципе неможет выводить больше одной картинки. Приходится использовать конструкцию типа: <img src='mini.php?name=tst.jpg'>, что бы собрать кучу миниатюр в одном браузере. Спасибо французу, который это описал. Не в одной русскоязычной статье таких подробностей небыло, видимо авторы подразумевали что сами должны догнать.
" ...и жалко и радостно, что не видят
исходных кодов пользователи...
...и плакать хочется, и радуешься,
что не узрят они твои велосипеды...
...и никто не узнает что же там на
самом деле...внутри...
...что не использовали мы стандартные
функции, а что живем мы правильно,
по-доброму...
...что все у нас хоть и криво, но родно..."--