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

PHP5_nachinayushim

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

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 16.6.

Рис. 16.7.

Рисование окружностей и эллипсов

Для рисования окружностей и эллипсов в PHP используется функция imageellipse().Она отличается тем, что внешние ограничения фигуры не указываются. Эл+ липс описывается координатами центральной точки, а также его высотой и шириной. Рассмотрим синтаксис функции:

imageellipse(resource image, int x, int y, int width, int height, int col);

Ниже приведен пример вызова:

imageellipse($myImage, 90, 60, 160, 50, $myBlack);

Центр эллипса, показанного на рис. 16.8, имеет координаты x = 90 и y = 60 в пиксе+ лях. Ширина эллипса равна 160 пикселей, а высота 50 пикселей.

Чтобы нарисовать круг, необходимо описать эллипс, ширина которого равна вы+ соте (рис 16.9):

imageellipse($myImage,90,60,70,70,$myBlack);

 

160

 

50

 

x = 90, y = 60

Рис. 16.8.

Рис. 16.9.

Рисование дуг

Дуга представляет собой часть эллипса, незамкнутую линию. Дуга описывается так же, как и эллипс за исключением того, что требуется задать дополнительные пара+ метры, определяющие начало и конец дуги. Начальная и конечная точки задаются в градусах. В полном эллипсе 360 градусов. 0 градусов ++++++ крайняя правая точка эллипса (три часа на циферблате часов). Углы отсчитываются по часовой стрелке (рис. 16.10):

Ниже приведен синтаксис функции imagearc():

imagearc(resource image, int x, int y, int width, int height, int start_degree, int end_degree, int col)

614 Глава 16

высота дуги

Рис. 16.10.

270 градусов

0 градусов

x, y

ширина дуги

Рассмотрим пример рисования незамкнутого эллипса с помощью функции imagearc():

imagearc($myImage,90,60,160,50,45,200,$myBlack);

Первый параметр ($myImage) идентифицирует создаваемое изображение. Два следующих параметра (90, 60) указывают центральную точку эллипса, по которой строится дуга. Параметры 160, 50 те же, что и в предыдущем примере эллипса. В дей+ ствительности создают дугу два следующих параметра: значение 45 указывает функ+ ции imagearc(), что дуга должна начинаться в позиции с углом 45 градусов (примерно 4:22 на циферблате часов) и заканчиваться в позиции с углом 200 граду+ сов. Следует отметить, что значение 200 ++++++ позиция в градусах от точки 0 градусов. На рис. 16.11 показана дуга 45++++200 градусов.

Рис. 16.11.

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

Рисование многоугольников

Многоугольник представляет собой фигуру, имеющую три или больше углов или вершин. Так как функция для рисования многоугольников (imagepolygon()) может создавать фигуры с разным количеством вершин, она принимает параметры, которые отличаются от параметров описанных выше функций. Кроме идентификатора изо+ бражения функции необходимо передать массив точек (координат x и y, определяющих

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

углы или вершины многоугольника). Второй параметр сообщает функции количество вершин создаваемого многоугольника.

int imagepolygon (resource image, array points, int num_points, int color)

Рассмотрим следующий код:

$myPoints = array(20,20,185,55,70,80); imagepolygon($myImage,$myPoints,3,$myBlack);

Сначала необходимо создать массив точек. В этом примере массив содержит шесть элементов ++++++ три пары x+ и y+координат. Это означает, что многоугольник имеет три угла: в точках 20,20, 185,55 и 70,80.

Затем вызывается функция imagepolygon(), которой передаются следующие па+ раметры:

1.Идентификатор изображения (ресурс).

2.Массив точек.

3.Количество вершин многоугольника.

4.Цвет линии, образующей создаваемую фигуру.

Полученный многоугольник показан на рис. 16.12.

Рис. 16.12.

Практика Рисование прямоугольника с закругленными углами

1. Откройте текстовый редактор и введите следующий код:

<?php

function roundrect($image, $x1, $y1, $x2, $y2, $curvedepth, $color) { imageline($image, ($x1 + $curvedepth), $y1, ($x2 - $curvedepth), $y1, $color); imageline($image, ($x1 + $curvedepth), $y2, ($x2 - $curvedepth), $y2, $color); imageline($image, $x1, ($y1 + $curvedepth), $x1, ($y2 - $curvedepth), $color); imageline($image, $x2, ($y1 + $curvedepth), $x2, ($y2 - $curvedepth), $color); imagearc($image, ($x1 + $curvedepth), ($y1 + $curvedepth), (2 * $curvedepth),

(2 * $curvedepth), 180, 270, $color);

imagearc($image, ($x2 - $curvedepth), ($y1 + $curvedepth), (2 * $curvedepth), (2 * $curvedepth), 270, 360, $color);

imagearc($image, ($x2 - $curvedepth), ($y2 - $curvedepth), (2 * $curvedepth), (2 * $curvedepth), 0, 90, $color);

imagearc($image, ($x1 + $curvedepth), ($y2 - $curvedepth), (2 * $curvedepth), (2 * $curvedepth), 90, 180, $color);

}

$myImage = imagecreate(200,100);

$myGrey = imagecolorallocate($myImage,204,204,204); $myBlack = imagecolorallocate($myImage,0,0,0);

616 Глава 16

roundrect($myImage, 20, 10, 180, 90, 20, $myBlack); header("Content-type: image/png"); imagepng($myImage);

imagedestroy($myImage); ?>

2.Сохраните файл как roundrect.php.

3.Откройте только что созданный файл в Web+браузере. Вывод сценария показан на рис. 16.13.

Рис. 16.13.

Как это работает

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

Сначала в сценарии создается функция для рисования прямоугольника с закруг+ ленными углами. Выделение этого кода в самостоятельную функцию позволит впо+ следствии использовать код повторно для рисования прямоугольников с другими па+ раметрами. Функция принимает семь параметров:

<?php

function roundrect($image, $x1, $y1, $x2, $y2, $curvedepth, $color) {

Первый параметр ++++++ идентификатор изображения, в котором создается прямо+ угольник. Два следующих параметра определяют верхний левый угол прямоугольника (поскольку углы закруглены, в этой точке фактически ничего не рисуется, она исполь+ зуется как точка привязки для левого верхнего угла прямоугольника). Два следующих параметра определяют правый нижний угол прямоугольника. Шестой параметр, $curvedepth, представляет собой расстояние (в пикселях) от угла прямоугольника до начала кривой. Последний параметр ++++++ цвет линий прямоугольника. На рис. 16.14 показано, как используются переданные функции roundrect() параметры.

В зависимости от того, какие линии и углы рисуются, используются различные комбинации параметров $x1, $x2, $y1, $y2 и $curvedepth.

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

глубина кривой

x1, y1

x2, y2

Рис. 16.14.

Сначала рисуется верхняя горизонтальная линия прямоугольника. Эта линия не должна соединять точки с координатами $x1 и $x2, так как необходимо учесть за+ кругление угла. Поэтому значение $curvedepth нужно прибавить к координате $x1 и вычесть из координаты $x2:

imageline($image, ($x1 + $curvedepth), $y1, ($x2 - $curvedepth), $y1, $color);

Поскольку эта линия горизонтальна, обе точки имеют одинаковую y+координату. Затем рисуется нижняя горизонтальная линия прямоугольника. В этом случае длину линии необходимо уменьшить на глубину кривой и использовать одинаковые y+коор+ динаты для обеих точек:

imageline($image, ($x1 + $curvedepth), $y2, ($x2 - $curvedepth), $y2, $color);

Далее рисуются две вертикальные линии, левая и правая стороны прямоугольника. На этот раз для двух точек каждой линии используется одна и та же x+координата ($x1 для левой стороны и $x2 для правой), а y+координаты соответствующим образом из+ меняются с учетом высоты кривой, образующей закругленные углы.

imageline($image, $x1, ($y1 + $curvedepth), $x1, ($y2 - $curvedepth), $color); imageline($image, $x2, ($y1 + $curvedepth), $x2, ($y2 - $curvedepth), $color);

Первая создаваемая кривая образует верхний левый угол. Необходимо указать центральную точку дуги (рис. 16.15), поэтому значение $curvedepth прибавляется к значениям $x1 и $y1. Кроме того, указывается ширина и высота дуги. Так как глу+ бина закругления фактически является радиусом дуги, чтобы получить ширину и вы+ соту дуги, ее глубину необходимо удвоить.

x1, y1

центральная точка дуги

Рис. 16.15.

Дуга начинается в позиции 180 градусов (9 часов) и продолжается до позиции 270 градусов.

imagearc($image, ($x1 + $curvedepth), ($y1 + $curvedepth), (2 * $curvedepth), (2 * $curvedepth), 180, 270, $color);

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

618 Глава 16

тать ее из координат x и y. Не забывайте о том, что начальные и конечные позиции дуг изменяются для каждого угла.

imagearc($image, ($x2 - $curvedepth), ($y1 + $curvedepth), (2 * $curvedepth), (2 * $curvedepth), 270, 360, $color); imagearc($image, ($x2 - $curvedepth), ($y2 - $curvedepth), (2 * $curvedepth), (2 * $curvedepth), 0, 90, $color); imagearc($image, ($x1 + $curvedepth), ($y2 - $curvedepth), (2 * $curvedepth), (2 * $curvedepth), 90, 180, $color);

Это все, что нужно для рисования прямоугольника с закругленными углами, по+ этому далее следует закрыть функцию и можно приступать к созданию изображения.

}

Создается пустое изображение, и в его палитру добавляются два цвета. Первый до+ бавляемый цвет будет фоновым цветом изображения:

$myImage = imagecreate(200,100);

$myGrey = imagecolorallocate($myImage,204,204,204); $myBlack = imagecolorallocate($myImage,0,0,0);

Затем вызывается функция roundrect(), которой передаются описанные выше параметры:

roundrect($myImage, 20, 10, 180, 90, 20, $myBlack);

Чтобы отправить изображение Web+браузеру, сначала отправляется заголовок, со+ общающий браузеру тип отправляемых данных. Это позволяет браузеру использовать корректную подпрограмму для отображения данных. В данном случае отправляется PNG+файл:

header("Content-type: image/png");

Затем используется функция imagepng(), которая отправляет данные самого изо+ бражения. Эта функция принимает один параметр, идентификатор изображения. В конце сценария используется функция imagedestroy() для очистки памяти.

imagepng($myImage); imagedestroy($myImage); ?>

Изменение растровых изображений

Ранее в этой главе рассматривалось создание изображений с помощью функций рисования библиотеки GD и практические примеры рисования базовых фигур одного цвета. А как же быть с растровыми изображениями, состоящими не из одного просто+ го цвета, а из миллионов точек разных цветов, например, с фотографиями? Библио+ тека GD позволяет не только создавать новые изображения с нуля, но и новые изо+ бражения на основе существующих JPEG+, PNG+ или GIF+изображений.

Открытие существующегоизображения

Для создания нового изображения используются функции imagecreate()и imagecreatetruecolor(). Чтобы создать новое изображение на основе существующего, применяют функции серии imagecreatefrom. Чаще всего используются функции imagecreatefromjpeg(), imagecreatefromgif() и imagecreatefrompng(). Су+ ществует также множество других функций, позволяющих создавать в памяти новые изображения на основе существующих, но они не так широко применяются, как три упомянутые выше функции.

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

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

Вызов

$myImage = imagecreatefromjpeg('moegie.jpg');

открывает JPEG+файл moegie.jpg, который находится в том же каталоге, что и исполняемый сценарий. Идентификатор изображения $myImage содержит данные JPEG+файла. Это можно проверить с помощью вывода данных изображения без каких+ либо предварительных операций с ними.

Практика Вывод JPEG-изображения в окно браузера

1. Введите в текстовом редакторе следующий код:

<?php

$myImage = imagecreatefromjpeg('moegie.jpg'); header("Content-type: image/jpeg"); imagejpeg($myImage);

imagedestroy($myImage); ?>

2. Сохраните файл как showjpeg.php. Убедитесь, что имя файла, передаваемое в качестве параметра функции imagecreatefromjpeg(), соответствует суще+ ствующему JPEG+файлу, который находится в том же каталоге, что и сценарий showjpeg.php.

3.Откройте страницу showjpeg.php в Web+браузере. Пример страницы показан на рис. 16.16.

Рис. 16.16.

620 Глава 16

Как это работает

Код сравнительно прост и не должен создавать проблемы. Сначала используется функция imagecreatefromjpeg() для создания нового ресурса изображения из су+ ществующего файла:

$myImage = imagecreatefromjpeg('moegie.jpg');

Затем Web+браузеру отправляется заголовок, сообщающий о передаче данных изо+ бражения:

header("Content-type: image/jpeg");

Теперь все, что осталось сделать, это отправить данные изображения и удалить изображение из памяти:

imagejpeg($myImage); imagedestroy($myImage);

В представленном примере нет ничего, что невозможно было бы сделать с помощью простого HTML. Однако, возможность открывать существующие изображения и мани+ пулировать ими до отправки в браузер полезна по многим причинам. Ниже перечисле+ ны некоторые возможности обработки изображений с помощью GD+функций.

Изменение размеров изображений для создания пиктограмм или понижение качества изображений для ускорения их загрузки в браузер.

Аннотирование изображения описательным текстом или подписью.

Копирование части одного изображения в другое для создания водяных знаков.

Рассмотрим создание водяных знаков в изображении, а также создание пикто+ грамм из изображений.

Внедрение водяных знаков

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

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

Рис. 16.17.

Копирование copyright-знака в изображение

Теперь откроем исходное изображение, в которое нужно вставить водяной знак:

<?php

$myImage = imagecreatefromjpeg('moegie.jpg');

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

Затем следует открыть copyright+знак или логотип. Так как это PNG+файл, для его открытия используется функция imagecreatefrompng().

$myCopyright = imagecreatefrompng('copyright.png');

Можно разместить copyright+знак в верхнем левом углу изображения. В таком слу+ чае нет необходимости в выполнении следующих этапов. Однако если требуется рас+ положить его справа, снизу или в центре изображения, то необходимо определить размеры обоих изображений. Функция imagesx() возвращает ширину изображения, а imagesy() ++++++ высоту. Обе функции принимают один параметр ++++++ ресурс, иденти+ фикатор изображения, размеры которого требуется определить. В рассматриваемом здесь примере copyright+знак помещается в центре изображения, поэтому необходимо определить ширину и высоту исходного изображения и copyright+знака:

$destWidth = imagesx($myImage); $destHeight = imagesy($myImage); $srcWidth = imagesx($myCopyright); $srcHeight = imagesy($myCopyright);

Далее нужно вычислить координаты левого верхнего угла copyright+знака в изо+ бражении. Эта задача решается простым вычитанием ширины copyright+знака из ши+ рины исходного изображения и последующим делением полученной разности на два. Для того чтобы получить y+координату, следует выполнить те же вычисления, но ис+ пользуя высоту изображений:

$destX = ($destWidth - $srcWidth) / 2; $destY = ($destHeight - $srcHeight) / 2;

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

Получив координаты для вставки copyright+знака, можно скопировать его в исход+ ное изображение. Для этого используется функция imagecopy():

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

Функция принимает восемь параметров, сообщающих ей, что копировать из исход+ ного изображения и куда помещать скопированный фрагмент в конечном изображении. Первым параметром является идентификатор изображения, куда будут скопированы данные, т.е. идентификатор того изображения, которое необходимо защитить водяным знаком. Второй параметр ++++++ идентификатор изображения, из которого будут скопиро+ ваны данные, т.е. copyright+знака. Третий и четвертый параметры ++++++ x+ и y+координаты

вконечном изображении, куда требуется скопировать данные. Эти координаты обозна+ чают левый верхний угол блока копируемых данных. Два следующих параметра (0,0

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

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

После того как данные скопированы, можно как обычно выводить изображение

вбраузер. Затем следует очистить память, занимаемую обоими изображениями:

header("Content-type: image/jpeg"); imagejpeg($myImage); imagedestroy($myImage);

622 Глава 16

imagedestroy($myCopyright); ?>

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

Рис. 16.18.

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

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]