Портал для веб-мастера
Вход пользователей
Поиск статей
WoWeb.ru » Статьи » Программирование для Web » PHP

Графика в PHP

Всякому web-программисту приходится работать с изображениями – чисто текстовых сайтов в интернете немного. Самый простой способ поместить на страницу картинку – сохранить ее в файле и поставить в HTML-файле соответствующий тэг. Один из недостатков этого способа очевиден: картинки, которые лежат в файле никак не меняются, чтобы пользователь увидел другое изображение, вебмастеру нужно открыть графический редактор, внести измения и сохранить их. В этой статье я расскажу о создании динамических изображений с помощью языка web-программирования PHP.

Для начала – несколько слов для тех, кто не знаком с PHP. Это – язык сценариев, выполняющихся на стороне сервера для создания динамических web-страниц. Программа на PHP, подобно тексту на JavaScript, VBScript или ASP, вставляется в HTML-файл или сохраняется в отдельном файле с соответствующим расширением. Начало и конец программы отмечаются специальными тэгами <? и ?>. Текст вне этих скобок PHP не интерпретирует, он передается web-браузеру «как есть». Синтаксис PHP довольно подробно описан в руководстве, которое входит в комплект поставки (его также можно взять на сайте http://www.php.net). 
Принцип работы с изображениями такой: PHP-программа (а точнее PHP-интерпретатор, работающий на стороне сервера) создает картинку «на лету» и передает ее браузеру в нужном графическом формате. 
Для того чтобы воспользоваться возможностями PHP по работе с изображениями, необходимо установить в системе библиотеку GD. Если вы работаете с Linux, то эта библиотека уже должна быть установлена. Если нет – ее можно найти по адресу http://www.boutell.com/gd. Если вы работаете с Windows, то лучше всего посетить http://php.weblogs.com/easywindows. Здесь можно скачать библиотеку php_gd, которая позволит вам насладиться всеми прелестями работы с графикой на PHP. Если вы планируете использовать в своих изображениях шрифты TrueType, вам понадобится библиотека FreeType (http://www.freetype.org). 
Несколько слов о поддерживаемых библиотекой GD графических форматах. Версии старше 1.6 поддерживают форматы GIF и JPEG. Более новые версии позволяют работать с JPEG и PNG. Начиная с версии 1.6 формат GIF в GD не поддерживается. Это связанно с тем, что всеми правами на алгоритм LZW-компрессии, использующийся в этом формате, обладает компания Unisys.

Первые шаги

Итак, система настроена, все необходимые библиотеки установлены. Для начала создадим какое-нибудь простое изображение:

<?
Header("Content-Type: image/gif");
$image = ImageCreate(500, 75);
$blue = ImagecolorAllocate($image, 0, 0, 255);
ImageFill($image, 1, 1, $blue);
ImageGIF($image);
ImageDestroy($image);
?>

Сохраните текст в файле с расширением .php и просмотрите его с помощью браузера. Если вы все сделали правильно, то вы увидите то, что показано на рисунке 1.

рисунок 1


Рассмотрим код нашего скрипта более подробно. В первой строчке скрипт сообщает браузеру информацию о типе передаваемых данных с помощью HTTP-заголовка. В нашем примере используется предопределенный тип «image/gif», который означает, что далее последует изображение в формате GIF. Передавать браузеру соответствующий заголовок необходимо всегда. Для форматов JPEG и PNG первая строчка выглядела иначе:

Header(“Content-Type: image/jpeg”);
Header(“Content-Type: image/png”);

Обратите внимание, что заголовок “Content-Type” передается для каждой страницы только один раз, поэтому PHP-код для генерации изображения необходимо помещать в отдельный файл. Кстати, размещение динамической графики вместе с HTML-кодом возможно только при использовании механизма SSI (Server Side Includes), о чем мы поговорим чуть позже. 
Создание графики в PHP состоит из четыре этапов:

  • создание дескриптора изображения; 

  • регистрация используемых цветов; 

  • рисование с использованием предопределенных функций; 

  • и финальная стадия – создание изображения и передача его браузеру.

В нашем примере первый этап выглядит так:

$image = ImageCreate(500, 75);

Здесь функция ImageCreate() создает дескриптор изображения и присваивается его переменной $image. Функция вызывается с двумя параметрами – высотой и шириной изображения. По умолчанию изображение заливается черным цветом. Следующий этап – цвета:

$blue = ImagecolorAllocate($image, 0, 0, 255);

Все используемые в изображении цвета необходимо регистрировать. Для этого используется функция ImageColorAllocate(); ее параметры – дескриптор изображения и RGB-кодировка цвета. Каждый цвет ставится в соответствие переменной, в дальнейшем эта переменная передается функциям рисования.
Вряд ли стоит перечислять все функции рисования. Скажу лишь, что их немало: вы можете «заливать» изображения цветом, рисовать различные фигуры, делать рисунок прозрачным и т.д. Рассмотрим некоторые из них на практике, а об остальных вы сможете узнать из документации.
В нашем первом примере мы «заливаем» изображение синим цветом с помощью функции

ImageFill:
ImageFill($image, 1, 1, $blue);

Второй и третий параметр – координаты начала заливки. Начало координат располагается в левом верхнем углу изображения. Таким образом, координаты (500, 75) определяют правый нижний угол изображения из первого примера.
Теперь следует передать готовый рисунок браузеру. Это делает функция ImageGIF(), ее единственный параметр – дескриптор изображения. Для форматов JPEG и PNG применяйте функции ImageJPEG() и ImagePNG() соответственно. Для освобождения памяти, выделенной под рисунок, в конце скрипта надо вызвать функцию ImageDestroy().

Использование текста в рисунках

Рассмотрим еще одну возможность: попробуем что-нибудь написать на рисунке. Я приведу небольшой пример, а потом поясню механизм работы с текстом:

<?
// передаем заголовок
Header("Content-Type: image/gif");

// создаем дескриптор изображения и регистрируем цвета
$image = ImageCreate(500, 75);
$black = ImageColorAllocate($image, 0, 0, 0);
$yellow = ImageColorAllocate($image, 255, 255, 0);

// выполняем "заливку" рисунка
ImageFill($image, 0, 0, $black);

// помещаем на изображение текст в координаты (210, 30)
itring($image, 4, 210, 30, "Hello World!", $yellow);

ImageGIF($image);
ImageDestroy($image);
?>

Результат выполнения скрипта показан на рисунке 2. 

рисунок 2

Собственно выводом текста занимается функция itrings(). Ее параметры – дескриптор изображения, номер шрифта, координаты точки вывода изображения, строка текста и цвет. Можно использовать один из пяти предопределенных шрифтов фиксированного размера. Они нумеруются от 1 (самый маленький) до 5 (самый большой). 
В следующем примере начинается самое интересное: изображение создается динамически на основе вводимых пользователем данных. Создадим простой HTML-файл с формой (рисунок 3).

рисунок 3

 Вот его код:

<html>
<body>
<form action="example3.php" method="get">
Введите Ваше имя:<input type=text name=name><br>
<input type=submit>
</form>
</body>
</html>

А теперь создадим такой файл example3.php:

<?
Header("Content-Type: image/gif");
if ($name)
{
$string = "Hello " . $name;
}
else
{
$string = "Hello All!";
}
$image = ImageCreate(500, 75);
$black = ImageColorAllocate($image, 0, 0, 0);
$yellow = ImageColorAllocate($image, 255, 255, 0);

ImageFill($image, 0, 0, $black);
itring($image, 4, 210, 30, $string, $yellow);

ImageGIF($image);
ImageDestroy($image);
?>

Изображение будет содержать введенный текст (рисунок 4).

рисунок 4


Скажу пару слов и о других функциях из библиотеки GD, предназначенных для работы с текстом. itringUp() выводит текст вертикально; ImageChar() и ImageCharUp() выводят один символ; ImageFontHeight() и ImageFontWidth() возвращают высоту и ширину шрифта. Последние две функции используются в следующем примере, в котором строка текста подчеркивается линией (функция ImageLine рисует линии по заданным координатам):

<?
Header("Content-Type: image/gif");
if ($name)
{
$string = "Hello " . $name;
}
else
{
$string = "Hello All!";
}
$image = ImageCreate(500, 75);
$black = ImageColorAllocate($image, 0, 0, 0);
$yellow = ImageColorAllocate($image, 255, 255, 0);
ImageFill($image, 0, 0, $black);
itring($image, 4, 210, 30, $string, $yellow);

// определяем ширину шрифта
$font_width = ImageFontWidth(4);

// вычисляем ширину строки введенного текста
$string_width = $font_width * (strlen($string));

// рисуем линию с началом в точке с координатами (210,50) 
ImageLine($image, 210, 50, (210+$string_width), 50, $yellow);

ImageGIF($image);
ImageDestroy($image);
?>

Результат работы скрипта показан на рисунке 5.

рисунок 5 

Что еще можно рисовать?

Естественно, кроме линий с помощью GD можно рисовать и другие фигуры. В следующем примере мы воспользуемся функцией ImageFilledRectangle() для того, чтобы вывести в окне браузера французский флаг. Функция предназначена для рисования заполненных определенным цветом прямоугольников. Для начала «зальем» весь рисунок белым цветом, а затем нарисуем красный и синий прямоугольники:

<?
// заголовок
Header("Content-Type: image/gif");
$image = ImageCreate(300, 300);

// регистрируем цвета
$red = ImageColorAllocate($image, 255, 0, 0);
$white = ImageColorAllocate($image, 255, 255, 255);
$blue = ImageColorAllocate($image, 0, 0, 255);

// выполняем "заливку" рисунка
ImageFill($image, 0, 0, $white);

// рисуем прямоугольники
ImageFilledRectangle($image, 0, 0, 100, 300, $blue);
ImageFilledRectangle($image, 200, 0, 300, 300, $red);

// передаем броузеру на клиентском компьютере
ImageGIF($image);
ImageDestroy($image);
?>

На рисунке 6 можно видеть результат наших трудов.

рисунок 6 

PHP позволяет рисовать и другие типы многоугольников. Для этого имеется функция ImagePolygon(). Следующий пример выводит на экран пятиугольник. В качестве параметров (кроме дескриптора изображения и цвета линии) этой функции передается следующая информация: количество вершин (в нашем случае – пять) и массив координат точек, являющихся вершинами. Результат работы скрипта представлен на рисунке 7.

<?
Header("Content-Type: image/gif");
$image = ImageCreate(300, 300);
$green = ImageColorAllocate($image, 0, 255, 0);
$white = ImageColorAllocate($image, 255, 255, 255);
$blue = ImageColorAllocate($image, 0, 0, 255);

// массив вершин многоугольника
$vertices = Array(150, 10, 250, 100, 250, 200, 50, 200, 50, 100);

ImageFill($image, 0, 0, $white);

// рисуем многоугольник
ImagePolygon($image, $vertices, 5, $blue);

// выполняем заливку многоугольника зеленым цветом (до синей границы)
ImageFillToBorder($image, 150, 150, $blue, $green);

ImageGIF($image);
ImageDestroy($image);
?>

рисунок 7

В этом же скрипте используется еще одна функция, не упоминавшаяся ранее – ImageFillToBorder(). Она используется для заливки области, ограниченной определенным цветом (в нашем случае это синяя линия многоугольника).
Функция ImageArc() умеет рисовать дуги и окружности. Приведу небольшой пример (см. рисунок 8):

<?
Header("Content-Type: image/gif");
$image = ImageCreate(300, 300);
$white = ImageColorAllocate($image, 255, 255, 255);
$black = ImageColorAllocate($image, 0, 0, 0);

// переменные для окружности:
// центр окружности
$center_x = 150;
$center_y = 150;

// высота и ширина
$width = 150;
$height = 150;

// начальный и конечный углы
$start = 0;
$end = 360;

ImageFill($image, 0, 0, $white);

// рисуем окружность
ImageArc($image, $center_x, $center_y, $width, $height, $start, $end, $black);

ImageGIF($image);
ImageDestroy($image);
?>

рисунок 8

Меняя значения переменных $width и $height, можно рисовать овалы, а меняя углы – добиться отображения различного рода дуг.

Использование готовых изображений

Библиотека GD позволяет не только рисовать картинки, но и пользоваться уже готовыми. Рассмотрим вполне реальную ситуацию: штатный дизайнер вашей фирмы разработал внешний вид кнопок для некоторого сайта, а вам надо поместить на странице несколько одинаковых по дизайну кнопок и подписи к ним.
В состав библиотеки GD входят такие функции, как ImageCreateFromGIF(), ImageCreateFromJPEG() и ImageCreateFromPNG(). Они помогут в тех случаях, когда надо создать новое изображение на основе уже существующего. Пусть у нас имеется файл button.gif (рисунок 9), который содержит гениальный дизайн кнопки для сайта. Ниже приводится PHP-код, который делает готовые кнопки на основе этого файла. Обратите внимание на то, как размеры кнопки, шрифта, и строк текста используются для вычисления координат размещения заголовков. Здесь в качестве подписи к кнопке берется значение переменной $caption, которая передается в скрипт извне:

<?
// файл button.php – помещение текста на рисунок.
// входные параметры:
// $caption - текст, размещаемый посередине рисунка
Header("Content-Type: image/gif");

// создаем изображение на основе существующего файла
$image = ImageCreateFromGIF("button.gif");

//регистрируем цвет
$white = ImageColorAllocate($image, 255, 255, 255);

// определяем размеры шрифта
$font_height = ImageFontHeight(3);
$font_width = ImageFontWidth(3);

// определяем размер рисунка
$image_height = iY($image);
$image_width = iX($image);

// получаем длину строки
$length = $font_width * strlen($caption);

// вычисляем начальные координаты для заголовка
$image_center_x = ($image_width/2)-($length/2);
$image_center_y = ($image_height/2)-($font_height/2);

// пишем текст
itring($image, 3, $image_center_x, $image_center_y, $caption, $white);

ImageGIF($image);
ImageDestroy($image);
?>

рисунок 9

Функции iX() и iY() возвращают, соответственно, ширину и высоту изображения. Также существует функция Getiize(), с помощью которой можно определить размеры и тип изображения.
Сам по себе приведенный выше скрипт большой практической ценности не имеет, но его можно использовать в любой HTML-странице посредством SSI или так, как описано в следующем коде:

<?
// данные для элементов меню:
// обычно такая информация получается из базы данных
// в данном примере массивы используются исключительно для простоты

$menu_items = Array();
$menu_items[0] = "News";
$menu_items[1] = "Documentation";
$menu_items[2] = "FAQ";
$menu_items[3] = "GuestBook";
$menu_items[4] = "Forum";
$menu_items[5] = "Send message";

?>

<html>

<body>
<center><h2>Make your choice!</h2></center>

<table border=0>

<?
// в цикле обрабатываем все элементы массива
foreach($menu_items as $caption)
{
// для каждого элемента выводим кнопку в отдельной строке таблицы
?>

<tr><td>
<a href="#"><img src="button.php?caption=<? echo $caption; ?>"
border=0></a>
</td></tr>

<?
}
?>

</table>

</body>
</html>

рисунок 10

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

<img src="button.php?caption=<? echo $caption; ?>"

Здесь в качестве параметра src тега img используется результат выполнения скрипта button.php, вызванного на выполнение с соответствующим значением параметра $caption.

Работаем с диаграммами

Теперь вы уже достаточно много знаете о возможностях библиотеки GD, поэтому в завершение нашего разговора я предлагаю создать какое-нибудь реальное приложение. Пример будет весьма жизненным – рисование диаграммы. В подавляющем большинстве случаев данные, которые отображает диаграммы, изменяются динамически (например, результаты голосования), поэтому PHP-скрипт здесь очень кстати. В примере мы рассмотрим создание разноцветной круговой диаграммы на основе вводимых пользователем данных. 
Для начала создадим HTML-файл, с формой, в которую пользователь будет вводить информацию, необходимую для формирования диаграммы. В нашем случае нужно просто ввести пять чисел. Вот HTML-код:

<html>
<body>
<h3>Создаем круговую диаграмму</h3>
<table>
<form action="pie.php" method=get>
<tr>
<td>Число №1</td>
<td><input type=text name=slice[1] value=0></td>
</tr>
<tr>
<td>Число №2</td>
<td><input type=text name=slice[2] value=0></td>
</tr>
<tr>
<td>Число №3</td>
<td><input type=text name=slice[3] value=0></td>
</tr>
<tr>
<td>Число №4</td>
<td><input type=text name=slice[4] value=0></td>
</tr>
<tr>
<td>Число №5</td>
<td><input type=text name=slice[5] value=0></td>
</tr>
<tr>
<td colspan=2 align=center><input type=submit value="Показать диаграмму!"></td>
</tr>
</form>
</table>

После нажатия кнопки «Показать диаграмму» введенные данные передаются скрипту pie.php. 
В скрипте все пять чисел суммируются. Затем считается, сколько процентов составляет каждое значение от всей суммы. Далее вычисляются углы дуг для каждой из «долек» и происходит, собственно, рисование дуг. Потом каждый сегмент заливается своим цветом. Для этого нужны координаты точки, находящейся внутри сегмента. В завершение над диаграммой помещается заголовок. Вот текст скрипта:

<?
// начнем с инициализации переменных
$sum = 0;
$degrees = Array();
$diameter = 200;
$radius = $diameter/2;
$center_x = 150;
$center_y = 150;

// в цикле вычисляем сумму введенных чисел
for ($x=1; $x<=5; $x++)
{
$sum += $slice[$x];
}

// преобразуем каждое значение в соответствующий процент от 360 градусов
for ($y=1; $y<=5; $y++)
{
$degrees[$y] = ($slice[$y]/$sum) * 360;
}

// создаем дескриптор изображения и инициализируем цвета
Header("Content-Type: image/gif");
$image = ImageCreate(300, 300);
$red = ImageColorAllocate($image, 255, 0, 0);
$blue = ImageColorAllocate($image, 0, 0, 255);
$green = ImageColorAllocate($image, 0, 255, 0);
$yellow = ImageColorAllocate($image, 255, 255, 0);
$black = ImageColorAllocate($image, 0, 0, 0);
$white = ImageColorAllocate($image, 255, 255, 255);

// первоначально зальем рисунок белым цветом
ImageFill($image, 0, 0, $white);

for ($z=1; $z<=5; $z++)
{
// в цикле вычисляем угол каждого сегмента и рисуем "дольки"
ImageArc($image, 150, 150, $diameter, $diameter, $last_angle,($last_angle+$degrees[$z]), $black);
$last_angle = $last_angle+$degrees[$z];

// вычисляем конечную точку каждой дуги 
// следует помнить, что функции cos() и sin() возвращают значения
// в радианах, которые должны быть преобразованы обратно в градусы
$end_x = round(150 + ($radius * cos($last_angle*pi()/180)));
$end_y = round(150 + ($radius * sin($last_angle*pi()/180)));

// разделяем сегменты черной линией
ImageLine($image, 150, 150, $end_x, $end_y, $black);
}

// теперь определим точки внутри сегментов для того,
// чтобы мы могли выполнить их заливку
$prev_angle = 0;
$pointer = 0;

for ($z=1; $z<=5; $z++)
{
$pointer = $prev_angle + $degrees[$z];
$this_angle = ($prev_angle + $pointer) / 2;
$prev_angle = $pointer;

$end_x = round(150 + ($radius * cos($this_angle*pi()/180)));
$end_y = round(150 + ($radius * sin($this_angle*pi()/180)));

$mid_x = round((150+($end_x))/2);
$mid_y = round((150+($end_y))/2);

// в зависимости от порядкового номера сектор
// выбираем тот или иной цвет
if ($z == 1)
{
ImageFillToBorder($image, $mid_x, $mid_y, $black, $red);
}
else if ($z == 2)
{
ImageFillToBorder($image, $mid_x, $mid_y, $black, $blue);
}
else if ($z == 3)
{
ImageFillToBorder($image, $mid_x, $mid_y, $black, $green);
}
else if ($z == 4) 
{
ImageFillToBorder($image, $mid_x, $mid_y, $black, $yellow);
}
else if ($z == 5)
{
ImageFillToBorder($image, $mid_x, $mid_y, $black, $black);
}
}

// выводим заголовок
itring($image, 5, 100, 10, "Pie Chart", $black);

ImageGIF($image);
ImageDestroy($image);
?>

рисунок 11

рисунок 12

На рисунке 11 показан пример заполнения формы, а на рисунке 12 – результат работы скрипта, соответствующий введенным данным. 

Еще несколько полезных функций

В заключение я упомяну еще несколько функций, которые могут быть полезны при изучении принципов работы с графикой в PHP.

  • ImageColorTransparent(). Принимает два аргумента – идентификатор изображения и цвет из палитры RGB (переменная PHP). Изображение заливается прозрачным цветом, указанным в переменной (второй аргумент). Функция применима только к GIF-изображениям.

  • ImageTTFText(). Прорисовывает текст с помощью TrueType шрифтов, которые разработчик может самостоятельно подключить. Второй аргумент указывает размер шрифта, третий – угол наклона будущего текста относительно горизонтали. 4-й и 5-й аргументы предназначены для указания координат начала текста (точнее, левого нижнего угла первой буквы текста) Обратите внимане: в функции itring все наоборот, там указываются координаты верхнего правого угла первой буквы текста. Далее идут цвет текста, шрифт (путь к файлу шрифта) и собственно текст.

  • ImageColorAt(). Возвращает цвет определенного пикселя в RGB-формате.

  • ImageColorExact(). Возвращает значение определенного (в переменной) цвета в RGB-формате.

  • ImageColorsTotal(). Возвращает общее количество цветов в палитре.

  • ietPixel(). Подсвечивает точку с указанными координатами указанным цветом.

На этом я закончу. Естественно, в рамках одной статьи невозможно рассмотреть все возможности работы с изображениями, предоставляемые языком PHP (точнее библиотекой GD), однако я надеюсь, что заинтересовал вас, и вы продолжите изучение этой темы.

Автор: Сергей Кривошеев · Добавлена: 2003-11-05
Просмотров: 12007 · Рейтинг: 4.2

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Категории раздела
Flash
Apache
WWW
PhotoShop
Веб-дизайн
Раскрутка и реклама
Базы данных
3D графика
Хостинг
Истории веб-мастеров
Web-технологии
Сетевая безопасность
Программирование для Web
Операционные системы

Новые статьи
Лучшие статьи
Популярные статьи
Комментируемые статьи
Разделы сайта
Скрипты
Статьи
Шрифты
Флэш исходники
HTML шаблоны
Партнерки
Клипарты
Смайлы
Фоны
Гифы
Иконки
Опрос сайта
Ведете ли вы блог?
Всего ответов: 59902
Наша кнопка
WoWeb.ru - портал для веб-мастера