Графика в PHP. Работа с библиотекой GD

Wednesday, 03 February 2010 | Автор: programmer

Данная статья предназначена уже для более продвинутых программистов, т.к. на начальном уровне работа с графикой вообще не нужна, но думаю будет очень интересна и для новичков, которые поймут, что на PHP можно создать все (конечно цитата взята из языка Cи "На Си++ можно написать все что угодно", но все равно очень подходит и для PHP).
В основу статьи положу создание PHP-класса работы с изображениями. Далее данный класс нам понадобится как для создания своей фотогалереи, так и апгрейда нашей гостевой книги, где мы будем делать капчу.
Но обо всем по порядку... Приступим к написанию нашего класса...

Создаем класс Image и конструктор для него.

class Image {
    var $im;
    var $width;
    var $height;
    var $type;

    function Image($fileName=false) {
        $this->fileName = $fileName;
        if ($fileName!==false)
            $this->load($fileName);
    }

    function load($fileName, $state=true) {
        if ($this->_info($fileName, $state)!== false) {
            $im = $this->_load($fileName, $this->type);
            if ($state === true)
                $this->im = $im;
        }
        else
            $this->error = 1;
    }

    function createImage($width, $height) {
        $this->im = imagecreatetruecolor ($width, $height);
    }

    private function _info($fileName, $state) {
        if (($result = getimagesize($fileName))!== false) {
            if ($state === true) {
                $this->width     = $result[0];
                $this->height     = $result[1];
                $this->type     = $this->_type($result[2]);
            }
            return array("width"=>$result[0], "height"=>$result[1], "type"=>$this->_type($result[2]));
        }
        else
            return 1;
    }

    private function _load($fileName, $type) {
        if ($type == "GIF")
            $im     = imagecreatefromgif($fileName);
        if ($type == "JPG")
            $im     = imagecreatefromjpeg($fileName);
        if ($type == "PNG")
            $im     = imagecreatefrompng($fileName);
        
        return $im;
    }

    private function _type($type) {
        switch ($type) {
            case 1: return 'GIF'; break;
            case 2: return 'JPG'; break;
            case 3: return 'PNG'; break;
            default: return false; break;
        }
    }
}


В конструктор передается один необязательный параметр $filename, который задает имя файла, с которым будет вестить работа. Если файл был передан при создании класса, то передает управление методу load(), которая пытается загрузить изображение. При создании двух функци _info() и _load() мы использовали следущие функции работы с изображениями:

    array getimagesize(string $filename);


На вход этой функции подается наименование файла изображения. На выходе Вы получаете массив сосотоящий из 7 элементов:
0 - ширина изображения
1 - высота изображения
2 - тип (формат) изображения
3 - тестовая строка вида 'width="xxx" height="yyy"' для использования в теге img
bits - битность канала изображения
channel - количество каналов в изображении, RGB имеет значение 3, CMYK - 4
mime - mine-тип изображения

    resource imagecreatefromgif(string $filename);
    resource imagecreatefromjpeg(string $filename);
    resource imagecreatefrompng(string $filename);


Эти функции создают новое изобращение из изображения переданного в функцию.

    resource imagecreatetruecolor (int $width, int $height)

Функция создает изображение шириной $width и высотой $height

Теперь напишем методы рисования простых фигур - прямоугольника и окружности.

    function rectangle($x, $y, $width, $height, $color) {
        if (!$this->im) {
            return imagerectangle($this->im, $x, $y, $x+$width, $y+$height, $this->_color($color));
        }
        else
            return false;
    }

    function circle($x, $y, $radiusX, $radiusY, $color) {
        if ($this->im) {
            return imageellipse($this->im, $x+ceil($radiusX/2), $y+ceil($radiusY/2), $radiusX, $radiusY, $this->_color($color));
        }
        else
            return false;
    }


Тут используется 2 функции imagerectangle и imageellipse для рисования прямоугольника и эллипса и функция imagecolorallocate для преобразования цвета в integer;

    bool imageellipse (resource $image, int $cx, int $cy, int $width, int $height, int $color);

В качестве параметров в эту функцию передаются следующие параметры:
$image - ресурс, возвращаемый функциями создания изображения
$cx и $cy - координата левого верхнего угла
$width - ширина прямоугольника
$height - высота прямоугольника
$color - цвет

    bool imagerectangle  ( resource $image  , int $x1  , int $y1  , int $x2  , int $y2  , int $color  )


$image - ресурс, возвращаемый функциями создания изображения
$x1 и $y1 - координата левого верхнего угла
$x2 и y2 - координата правого нижнего угла
$color - цвет

int imagecolorallocate (resource $image, int $red, int $green, int $blue);


$image - ресурс, возвращаемый функциями создания изображения
$red, $green, $blue - значение в диапазоне от 0 до 255 для цветов красного, зеленого, синего

Теперь создадим 3 метода класса для сохранения изображения в формате JPG, GIF, PNG, назовем их saveJpg, saveGif, savePng.

    function saveGif($fileName) {
        if (!imagegif($this->im, $fileName))
            return false;
        else
            return true;
    }
    
    function saveJpg($fileName) {
        if (!imagejpeg($this->im, $fileName))
            return false;
        else
            return true;
    }
    
    function savePng($fileName) {
        if (!imagepng($this->im, $fileName))
            return false;
        else
            return true;
    }


При создании этих методов мы использовали 3 php функции для работы с графикой: imagegif, imagejpeg, imagepng.

    bool imagegif (resource $image [, string $filename]);

Сохранение изображение в формате GIF.
$image - ресурс, возвращаемый функциями создания изображения
$filename - необязательный параметр, если задан, то изображение сохраняется в файл, если нет, то выводится на экран

bool imagejpeg (resource $image [, string $filename [, int $quality]]);
[/code]
$image - ресурс, возвращаемый функциями создания изображения
$filename - необязательный параметр, если задан, то изображение сохраняется в файл, если нет, то выводится на экран
$quality - качество изображения, измеряется от 0 (наименьшее качество) до 100 (наилучшее качество)

    bool imagepng (resource $image [, string $filename [, int $quality [, int $filters  ]]]);


$image - ресурс, возвращаемый функциями создания изображения
$filename - необязательный параметр, если задан, то изображение сохраняется в файл, если нет, то выводится на экран
$quality - качество изображения, измеряется от 0 (наименьшее качество) до 100 (наилучшее качество)
$filters - наложение фильтров на PNG-изображение осуществляется параметром из справочника допустимых значений PNG_FILTER_XXX. PNG_NO_FILTER отключает все фильтры, PNG_ALL_FILTERS включает все фильтры.

Осталось нам написать еще одну функцию - это метод в классе будет отвечать за вывод текста на изображение, назовем этот метод text()
    function text ($text, $posInfo=array()) {
        if (!isset($posInfo['hoffset']))
            $posInfo['hoffset'] = 5;
        if (!isset($posInfo['woffset']))
            $posInfo['woffset'] = 5;
        if (!isset($posInfo['position'])) // LT - левый верхний угол, RT - правый верхний угол, LB - левый нижний угол, RB - правый нижний угол
            $posInfo['position'] = "RB";
        if (!isset($posInfo['size']))
            $posInfo['size'] = 8;
        if (!isset($posInfo['angle']))
            $posInfo['angle'] = 0;
        if (!isset($posInfo['color']))
            $posInfo['color'] = $this->_color("#000000");
        else
            $posInfo['color'] = $this->_color($posInfo['color']);

        $info        = ImageTTFBBox($posInfo['size'], $posInfo['angle'], 'font/verdana.ttf', $this->_toUnicode($text) );
        $widthText    = $info[4]-$info[6];
        $heightText    = $info[1]-$info[7];

        $posX = (isset($posInfo['position'])? ($posInfo['position']=="LT" || $posInfo['position']=="LB"? $posInfo['woffset']: ($posInfo['position']=="RT" || $posInfo['position']=="RB"? $this->width-$widthText-$posInfo['woffset']: $this->width-$widthText-$posInfo['woffset'])): $this->width-$widthText-$posInfo['woffset']);
        $posY = (isset($posInfo['position'])? ($posInfo['position']=="LT" || $posInfo['position']=="RT"? $posInfo['hoffset']: ($posInfo['position']=="LB" || $posInfo['position']=="RB"? $this->height-$heightText-$posInfo['hoffset']: $this->height-$heightText-$posInfo['hoffset'])): $this->height-$heightText-$posInfo['hoffset']);

        ImageTTFText($this->im, $posInfo['size'], $posInfo['angle'], $posX, $posY, $posInfo['color'], 'font/verdana.ttf', $this->_toUnicode($text));
    }


На вход будут подаваться 2 параметра - сам текст, который необходимо вывести и массив параметов, в который будут входить такие параметры как: смещения от краев изображение по горизонтали и вертикали (hoffset и woffset соответственно), позиция вывода текста position (можно в принципе добавить два параметра $x и $y если выходите выводить текст в произвольных координатах ихображения), размер шрифта изображения size, угол поворота текста angle и цвет текста color.

array imagettfbbox ( float $size, float $angle, string $fontfile, string $text);

Данная функция возвращает возвращает массив состоящий из 8 элементов, которые представляют собой координаты прямоугольника, в который вписан текст. Функция дает нам возможность узнать длину и высоту текста в пикселях для последующего вывода текста на изображении в определенных координатах.
$size - размер шрифта
$angle - угол поворота текста
$fontfile - имя файла с TTF шрифтом
$text - сама строка текста для вывода

array imagettftext (resource $image, float $size, float $angle, int $x, int $y, int $color, string $fontfile, string $text)

Фунция imagettftext выводит текст на изображении в заданных координатах с заданным углом вывода текста.
$image - ресурс, возвращаемый функциями создания изображения
$size - размер шрифта
$angle - угол поворота текста
$x - левый верхний угол по оси X
$y - левый верхний угол по оси Y
$color - цвет текста
$fontfile - имя файла с TTF шрифтом
$text - строка текста для вывода

Также Вы можете увидеть что мы используем метод _toUnicode для преобразования текста в формат UTF. Это нужно для того, чтобы выводить русский текст.

А вот теперь дошли до самого интересного, попробуем написать маленький скрипт, который создаст нам изображение размером 500х500 и нарисует в нем квадрат с окружностью и добавит текст.

    include "image.php";
    $image = new Image();
    $image->createImage(500, 500);
    $image->rectangle(20, 20, 200, 200, "#FF0000");
    $image->circle(0, 0, 200, 200, "#00FF00");
    $image->text("Заходи на http://phpprogs.ru/", array("size"=>16, "angle"=>45, "color"=>"#FF0000"));
    $image->saveJpg("test.jpg");


В итоге мы получим такое изображение:

 

Работа с графикой в PHP

 

Скачать класс работы с изображениями в PHP можно тут: http://phpprogs.ru/uploads/imageClass.rar

Обсуждение работы скрипта: http://phpprogs.ru/forum/


 
Tweet


Категория(и): Изучаем PHP, Скрипты

Комментарии


Friday, 05 February 2010 | 11:36:51 | Автор: my
Неплохо для начала =)
Sunday, 27 February 2011 | 13:26:47 | Автор: theone

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

Добавить комментарий
Чтобы оставить комментарий, Вам необходимо зарегистрироваться или авторизироваться