Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

web - tec / PHP 5 для начинающи

.pdf
Скачиваний:
72
Добавлен:
12.06.2015
Размер:
26.79 Mб
Скачать

622 Глава 16

imagedestroy($myCopyright); ?>

На рис. 16.18 показан результат создания водяного знака в изображении.

Рис. 16.18.

Одно из требований к водяному знаку состоит в том, что первоначальное изобра+ жение должно оставаться узнаваемым. На рисунке часть изображения теперь закрыта. Необходимо улучшить сценарий так, чтобы copyright+знак закрывал как можно мень+ шую часть изображения.

Использование прозрачности

Можно скопировать не все изображение, а только текст. Для этого нужно сделать белую область copyright+знака прозрачной. Необходимая для этого функция работает с идентификаторами цветов, поэтому прежде чем сделать область прозрачной, следу+ ет получить индекс белого цвета. Для этого существует несколько способов ++++++ можно использовать функцию imagecolorat(), которая возвращает индекс цвета для точно указанного пикселя в изображении, или точно указать цвет и попытаться получить индекс этого цвета в палитре. Единственный недостаток последнего способа заклю+ чается в том, что если указанный цвет отсутствует в палитре изображения, то полу+ чить корректный идентификатор изображения не удастся. Ранее copyright+знак был сохранен как 8+цветное PNG+изображение. Это было сделано потому, что в работе ис+ пользовалась только небольшая палитра и можно было уверенно полагать, что белый фон изображения будет одинаковым во всем изображении. Если бы изображение бы+ ло сохранено как JPEG с миллионами цветов, то сглаживание в изображении могло бы привести к появлению некоторых вариаций фонового цвета, что усложнило бы

Генерирование графики 623

точное указание белого цвета (который необходимо сделать прозрачным). (Сглаживание цветов означает метод, при котором цвет формируется путем помеще+ ния рядом двух пикселей разных цветов.) Сохраняя изображение в формате PNG с небольшим количеством цветов, можно избежать эффекта сглаживания.

Для возвращения индекса цвета (в данном случае белого) используется функция imagecolorexact(). (Ее синтаксис описывается в приложении Б, ‘‘Справочник по PHP+функциям’’.) Функция imagecolorexact() принимает четыре параметра ++++++

идентификатор ресурса изображения и значения красного, зеленого и синего для цвета, который необходимо найти. Поскольку в данном случае изображение имеет только во+ семь цветов, можно быть уверенным, что будет возвращен корректный индекс цвета.

После получения индекса цвета используется функция imagecolortransparent(), которая делает указанный цвет в изображении прозрачным. Эта функция принимает два параметра: идентификатор ресурса изображения и индекс цвета, который необхо+ димо сделать прозрачным. Показанные ниже выделенные строки кода вставляются в первоначальную часть сценария ++++++ они следуют сразу за вычислением конечных коор+ динат x и y и перед копированием данных из одного изображения в другое.

$destY = ($destHeight - $srcHeight) / 2;

$white = imagecolorexact($myCopyright, 255, 255, 255); imagecolortransparent($myCopyright, $white);

imagecopy($myImage, $myCopyright, $destX, $destY, 0, 0, $srcWidth, $srcHeight);

Теперь вывод сценария выглядит корректнее (рис. 16.19).

Рис. 16.19.

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.

630 Глава 16

GD*библиотека для Windows*инсталляции PHP поддерживает шрифты True Type. В Unix пользователям перед компиляцией PHP необходимо установить библиотеку FreeType. Библиотека FreeType доступна на сайте www.freetype.org.

Результатом использования шрифтов True Type является большая гибкость ++++++

можно не только контролировать внешний вид текста, выбирая подходящий шрифт, но и указывать размер шрифта и угол наклона строки текста. Для этого предпочти+ тельнее применять функцию imagefttext(), которая использует библиотеку Free+ Type 2 для рисования True Type+текста. Эта функция принимает параметры, анало+ гичные параметрам функции imagestring(), но в другом порядке, и некоторые параметры используются иначе.

Практика Шрифты True Type

Рассмотрим сценарий truetype.php:

<?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");

header("Content-type: image/png"); imagepng($textImage); imagedestroy($textImage);

?>

На рис. 16.24 показан текст, написанный шрифтом Arial размером 16 пикселей. Значение 0 указывает на то, что текст рисуется слева направо под углом 0 градусов (т.е. горизонтально).

Рис. 16.24.

Генерирование графики 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+функций с цветами, был также описан процесс рисования различных фигур и текста в изображениях.

Соседние файлы в папке web - tec