web - tec / PHP 5 для начинающи
.pdf622 Глава 16
imagedestroy($myCopyright); ?>
На рис. 16.18 показан результат создания водяного знака в изображении.
Рис. 16.18.
Одно из требований к водяному знаку состоит в том, что первоначальное изобра+ жение должно оставаться узнаваемым. На рисунке часть изображения теперь закрыта. Необходимо улучшить сценарий так, чтобы copyright+знак закрывал как можно мень+ шую часть изображения.
Использование прозрачности
Можно скопировать не все изображение, а только текст. Для этого нужно сделать белую область copyright+знака прозрачной. Необходимая для этого функция работает с идентификаторами цветов, поэтому прежде чем сделать область прозрачной, следу+ ет получить индекс белого цвета. Для этого существует несколько способов ++++++ можно использовать функцию imagecolorat(), которая возвращает индекс цвета для точно указанного пикселя в изображении, или точно указать цвет и попытаться получить индекс этого цвета в палитре. Единственный недостаток последнего способа заклю+ чается в том, что если указанный цвет отсутствует в палитре изображения, то полу+ чить корректный идентификатор изображения не удастся. Ранее copyright+знак был сохранен как 8+цветное PNG+изображение. Это было сделано потому, что в работе ис+ пользовалась только небольшая палитра и можно было уверенно полагать, что белый фон изображения будет одинаковым во всем изображении. Если бы изображение бы+ ло сохранено как JPEG с миллионами цветов, то сглаживание в изображении могло бы привести к появлению некоторых вариаций фонового цвета, что усложнило бы
624 Глава 16
Белесый контур вокруг цифр 2004 в изображении связан с эффектом сглаживания (anti+aliasing) шрифта. Если такой эффект нежелателен, то можно отключить сглажи+ вание шрифта в графическом редакторе либо сохранить copyright+знак как двухцвет+ ное изображение в формате PNG. Как и следовало ожидать, очень сложно получить гладкую кривую в небольшом пиксельном диапазоне, который характерен для симво+ лов шрифта. При сглаживании шрифта используются оттенки цвета шрифта для соз+ дания плавного перехода кривых шрифта в фон изображения, чтобы буквы не имели зазубренных краев. Это означает, что закругления шрифта составляются из различ+ ных оттенков цвета, и когда фоновый цвет изображения становится прозрачным, по+ следствия сглаживания шрифта оказываются видимыми (см. рис. 16.19). Выключение сглаживания или сохранение изображения как двухцветного делает шрифт немного неровным, но вместе с тем удаляет контур вокруг цифр 2004. Чтобы уменьшить этот эффект и сделать водяной знак менее бросающимся в глаза, можно было бы изменить непрозрачность копируемых в изображение данных.
Использование непрозрачности
Степень непрозрачности (opacity) изображения может изменяться от полностью прозрачного (через изображение видно другое изображение) до полностью непро+ зрачного, когда сквозь одно изображение другого изображения не видно. В предыду+ щем разделе черный текст copyright+знака был непроницаемым, хотя фон был про+ зрачным. Чтобы водяной знак не так бросался в глаза, можно использовать функцию imagecopymerge(), которая позволяет придать копируемым данным некоторую сте+ пень прозрачности. Эта функция работает аналогично imagecopy() кроме того, что она принимает девятый параметр, который управляет прозрачностью копируемого изображения. Если значение этого параметра равно 0, то цвет будет полностью про+ зрачным и копируемые данные будут не видны, а значение 100 приводит к полной непрозрачности копируемого изображения, и в этом случае данная функция ведет се+ бя как imagecopy(). Изменим следующую строку сценария:
imagecopy($myImage, $myCopyright, $destX, $destY, 0, 0, $srcWidth, $srcHeight);
на
imagecopymerge($myImage, $myCopyright, $destX, $destY, 0, 0, $srcWidth, $srcHeight, 50);
Функция imagecopy() заменена imagecopymerge() и указан дополнительный параметр со значением 50 ++++++ среднее значение между прозрачностью и непрозрачно+ стью. Вывод сценария теперь намного больше похож на водяной знак (рис. 16.20).
Читателям, которые интересуются эффектами прозрачности в изображениях, можно порекомендовать ознакомиться с описанием функций imagecolorallocatealpha() и imagealphablending() в руководстве по PHP. И хотя воспроизвести в PHP все возможности, доступные для профессиональной программы редактирования графи+ ки, не удастся, некоторые интересные эффекты все+таки получить можно.
В следующем разделе рассматривается изменение существующих изображений, но на этот раз речь пойдет об уменьшении размеров изображения до пиктограммы.
Создание пиктограмм
При создании пиктограммы изображения используется метод, аналогичный вне+ дрению водяного знака, за исключением того, что копирование осуществляется в дру+ гом направлении. Вместо копирования меньшего изображения в большее, большое изображение копируется в новое, пропорционально уменьшенное изображение.
Генерирование графики 625
Рис. 16.20.
1.Создайте файл thumbnail.php, выберите изображение, сохраните его как moegie.jpg и следуйте описанным далее этапам создания пиктограммы.
2.Откройте изображение, для которого планируется создать пиктограмму:
<?php
$mainImage = imagecreatefromjpeg('moegie.jpg');
3.Используйте функции imagesx() и imagesy() для определения ширины и высоты исходного изображения. Эти данные необходимы для вычисления раз+ мера нового изображения (пиктограммы):
$mainWidth = imagesx($mainImage); $mainHeight = imagesy($mainImage);
4.В этом примере создается пиктограмма, размеры которой в четыре раза мень+ ше размеров исходного изображения, поэтому исходную ширину и высоту нуж+ но разделить на 4. В результате должны получиться целые числа, потому что невозможно использовать половину пикселя:
$thumbWidth = intval($mainWidth / 4); $thumbHeight = intval($mainHeight / 4);
Необязательно масштабировать изображение таким способом. Можно уменьшать изображение до определенных размеров, так чтобы ширина и высота новой пиктограммы попадали в заданный диапазон. Или можно сделать так, чтобы все пиктограммы имели одинаковую ширину, и масштабировать их соответствующим образом.
626Глава 16
Важно то, что ширина и высота должны изменяться пропорционально, чтобы пиктограмма не получилась ‘‘сплющенной’’.
5.Создайте новое пустое изображение, имеющее ширину и высоту пиктограммы. Как правило, пиктограммы создаются для изображений фотографического ти+ па, поэтому пиктограмма должна иметь большое количество цветов; для ее соз+ дания используется функция imagecreatetruecolor():
$myThumbnail = imagecreatetruecolor($thumbWidth, $thumbHeight);
Теперь следует уменьшить исходное изображение и скопировать его в новую пикто+ грамму. Это можно сделать с помощью одной из двух функций ++++++ imagecopyresized() или imagecopyresampled(). Разница между ними заключается в том, что imagecopyresized() работает быстрее, но совсем не сглаживает изображение. Если с по+ мощью этой функции создать пиктограмму, а затем увеличить ее, то будет заметен эффект мозаичности изображения (рис. 16.21).
Рис. 16.21.
Функция imagecopyresampled() хотя и работает медленнее, интерполирует пик+ сели так, что изображение не искажается. Обе функции: как imagecopyresized(), так и imagecopyresampled() ++++++ принимают одинаковый набор из 10 параметров. Пер+ вые два параметра ++++++ идентификатор конечного изображения и идентификатор изо+ бражения, из которого копируются данные. Вторая пара параметров ++++++ x+ и y+ координаты левого верхнего угла блока данных в конечном изображении, в который вставляются данные копируемого изображения. В этом примере используются коор+ динаты 0,0, т.е. пиктограмма будет полностью заполнена изображением. Следующие два параметра сообщают функции, откуда начинать копирование данных исходного изображения. В рассматриваемом примере используются все данные, поэтому копи+ рование начинается с левого верхнего угла в позиции 0,0. Два следующих параметра сообщают функции, как изменится ширина и высота блока данных в конечном
Генерирование графики 627
изображении. Значения этих параметров должны быть вычислены заранее ++++++ шири+ на и высота пиктограммы. Два последних параметра определяют ширину и высоту блока графических данных, которые копируются из исходного изображения. В этом примере используется ширина и высота исходного изображения, поскольку в пикто+ грамму копируется все изображение.
Копировать все изображение необязательно, можно скопировать только неболь+ шую его часть. Так как в конечном изображении разрешается устанавливать любую ширину или высоту блока данных, можно случайно скопировать блок непропорциональ+ ных размеров, поэтому нужно тщательно вычислять ширину и высоту изображений.
6.Для копирования данных изображения в пиктограмму используется функция imagecopyresampled():
imagecopyresampled($myThumbnail, $mainImage, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $mainWidth, $mainHeight);
7.Изображение отправляется браузеру (рис. 16.22), а память, используемая сце+ нарием, очищается:
header("Content-type: image/jpeg"); imagejpeg($myThumbnail); imagedestroy($myThumbnail); imagedestroy($mainImage);
?>
Рис. 16.22.
Использование текста в изображениях
Возможность добавлять с помощью PHP+фукнций текст в изображения позволяет аннотировать изображения или создавать динамические диаграммы и графики. Са+ мый простой и самый быстрый способ добавления текста в изображение заключается
виспользовании функции imagestring(), которая позволяет вставить строку текста
вуказанную область изображения.
628 Глава 16
Добавление стандартного текста
Функция imagestring() облегчает вставку текста в изображение, потому что она может использовать встроенные системные шрифты и не вынуждает пользователя за+ гружать на сервер шрифты в подходящем формате.
Ниже показан синтаксис функции imagestring():
imagestring (image, font, x, y, text, color)
Как обычно, в качестве первого параметра передается идентификатор изображения. Второй параметр определяет используемый шрифт. Значением этого параметра явля+ ется целое число больше нуля. Значения от 1 до 5 представляют встроенные системные шрифты, а любые шрифты, загруженные позднее, представлены значениями больше 5.
Чтобы загрузить шрифт для функции imagestring(), применяется функция imageloadfont(). Она загружает растровый зависимый от архитектуры шрифт ****** это означает, что шрифт должен быть сгенерирован на системе такого же типа, что и серверная система, на которой шрифт будет использоваться. Гораздо проще использовать шрифты True Type ****** этот метод рассматривается далее.
Параметры x и y позволяют позиционировать шрифт в изображении. Эти значе+ ния представляют собой координаты левого верхнего угла прямоугольника, в кото+ ром будет расположен текст. Два последних параметра ++++++ собственно текст, который должен появиться в изображении, и цвет, которым он будет нарисован.
Практика Отображение системных шрифтов
Следующий сценарий (drawstring.php) демонстрирует внешний вид системных шрифтов.
<?php
$textImage = imagecreate(200,100);
$white = imagecolorallocate($textImage, 255, 255, 255); $black = imagecolorallocate($textImage, 0, 0, 0); $yOffset = 0;
for ($i = 1; $i <=5; $i++) {
imagestring($textImage, $i, 5, $yOffset, "This is system font $i", $black); $yOffset += imagefontheight($i);
}
header("Content-type: image/png"); imagepng($textImage); imagedestroy($textImage);
?>
На рис. 16.23 показан результат работы этого сценария.
Как это работает
Сначала создается пустое изображение для текста, а затем добавляются белый и черный цвет. Так как белый цвет добавляется первым, он будет фоновым цветом изображения.
<?php
$textImage = imagecreate(200,100);
$white = imagecolorallocate($textImage, 255, 255, 255); $black = imagecolorallocate($textImage, 0, 0, 0);
Генерирование графики 629
Рис. 16.23.
Затем инициализируется переменная для хранения y+координаты (расстояние от верхнего края изображения) строки текста. В рассматриваемом примере текст раз+ мещается вверху изображения, поэтому значение переменной равно 0.
$yOffset = 0;
Далее в цикле просматриваются все встроенные системные шрифты.
for ($i = 1; $i <=5; $i++) {
В каждой итерации цикла создается строка с использованием шрифта с идентифи+ катором $i, который изменяется в цикле от 1 до 5. Строка позиционируется на рас+ стоянии 5 пикселей от левой границы изображения и на расстоянии $yOffset от верхней границы.
imagestring($textImage, $i, 5, $yOffset, "Это системный шрифт $i", $black);
Функция imagefontheight() принимает идентификатор шрифта и возвращает высоту шрифта в пикселях. Возвращенное этой функцией значение прибавляется к $yOffset для того, чтобы строки текста выводились одна под другой и не на+ кладывались друг на друга. (Ширину шрифта можно получить с помощью функ+ ции imagefontwidth().)
$yOffset += imagefontheight($i);
Наконец, изображение отправляется браузеру и выполняется очистка памяти.
}
header("Content-type: image/png"); imagepng($textImage); imagedestroy($textImage);
?>
Использование шрифтов True Type
При создании простейших диаграмм и графиков предпочтительнее использовать встроенные системные шрифты, поскольку они моноширинные ++++++ все символы шрифта имеют одинаковую ширину ++++++ и это облегчает позиционирование. Однако чтобы сделать текст более изящным, следует использовать шрифты True Type.
Генерирование графики 631
Как это работает
Сначала создается пустое изображение и выделяется два цвета.
<?php
$textImage = imagecreate(200,100);
$white = imagecolorallocate($textImage, 255, 255, 255); $black = imagecolorallocate($textImage, 0, 0, 0);
Затем в изображение вставляется строка текста:
imagefttext($textImage, 16, 0, 10, 50, $black,"C:\Windows\fonts\arial.ttf", "Arial, 16 pixels");
Первый параметр ++++++ идентификатор изображения, которое необходимо изменить. Второй параметр определяет размер шрифта ++++++ высоту шрифта в пикселях. Следую+ щий параметр определяет угол наклона текста. Угол в данном случае отсчитывается так же, как и в функции imagearc(), но угол определяет направление написания текста. Так как позиция 0 градусов соответствует 3 часам на циферблате часов, текст рисуется в направлении слева направо. Эта функция значительно отличается от imagearc() тем, что вращение выполняется против часовой стрелки (пример вращения показан ниже). Следующие два параметра определяют x+ и y+координаты начала строки ++++++
левый нижний угол ограничивающего блока вокруг текста; это отличается от функции imagestring(), в которой координаты отсчитываются от левого верхнего угла ограничивающего блока. Затем необходимо указать полный системный путь к файлу шрифта (TTF) на жестком диске. Последний параметр ++++++ строка, которую не+ обходимо вставить в изображение.
Работа сценария завершается как обычно:
header("Content-type: image/png"); imagepng($textImage); imagedestroy($textImage);
?>
Чтобы изобразить повернутый текст, необходимо заменить строку:
imagefttext($textImage, 16, 0, 10, 50, $black,"C:\Windows\fonts\arial.ttf", "Arial, 16 pixels");
на:
imagefttext($textImage, 16, -30, 10, 30, $black,"C:\Windows\fonts\arial.ttf", "Arial, 16 pixels");
Изменилось направление рисования текста: ++++30 градусов вместо 0. Как уже было сказано, вращение в этой функции выполняется против часовой стрелки, поэтому от+ рицательное число соответствует повороту текста по часовой стрелке. Если 0 граду+ сов совпадает с 3 часами, то 30 градусов по часовой стрелке совпадает с 4 часами на циферблате. На рис. 16.25 отчетливо видно, как наклонен текст.
Резюме
В этой главе рассматривалось создание и вывод изображений с помощью PHP. В при+ мерах было показано, как комбинировать два изображения с целью вставки водяного зна+ ка, как открывать и использовать существующие изображения для создания пиктограмм. Полученные знания помогут разработчикам расширить свои сценарии и Web+страницы.
Кроме того, в главе освещалась работа PHP+функций с цветами, был также описан процесс рисования различных фигур и текста в изображениях.