Скрипт фотогалереи. Том 1. Глава 1

Friday, 05 February 2010 | Автор: programmer

Как и о бещал в предыдущей статье, будем пытаться создать скрипт фотогалереи. Это опять же будет цикл статей, а вот именно эту статью назовем "Скрипт фотогалереи. Том 1. Глава 1.". Первый том будет состоять 3 глав.  В первой главе рассмотрим не так много, но это нам очень поможет при создании галереи, а именно в наш класс для работы с изображениями в PHP мы добавим 2 функции: создание уменьшенной копии изображения, наложение "водяных знаков" (логотипа). Во-второй статье будем создавать backend-интерфейс (в простонародии админку) для добавления категорий фотогалереи и самих фотографий. В третьей главе мы создадим frontend-интерфейс, который будет видеть конечный пользователь нашей фотогалереи. И по прошествии трех глав у нас получится фотогалерея с начальным набором функций. Но дальше будет интереснее, так что следите за новыми статьями :)


Итак, как и говорил выше, в этой статье мы создадим всего 2 функции. Первая функция уменьшения изображения:

    function resize($width, $height, $proportion=false, $bgcolor="#000000") {
        if (is_resource($this->im)) {
            if ($proportion) {
                $temp = imagecreatetruecolor($width, $height);
                imagefilledrectangle($temp, 0, 0, $width, $height, $this->_color($bgcolor));
                if ($width / $this->width > $height/$this->height) {
                    $newHeight = $height;
                    $newWidth = $this->width/($this->height/$height);
                }
                else {
                    $newHeight = $this->height/($this->width/$width);
                    $newWidth = $width;
                }

                imagecopyresized($temp, $this->im, ceil(($width-$newWidth)/2), ceil(($height-$newHeight)/2), 0, 0, $newWidth, $newHeight, $this->width, $this->height);
                $this->im = $temp;
            }
            else {
                $temp = imagecreatetruecolor($width, $height);
                imagecopyresized($temp, $this->im, 0, 0, 0, 0, $width, $height, $this->width, $this->height);
                $this->im = $temp;
            }
        }
        else
            return false;
    }


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

Из нерассмотренных ранее PHP-функций работы с графикой у нас в этом методе есть 2 функции:
    bool imagefilledrectangle (resource $image, int $x1, int $y1, int $x2, int $y2, int $color)

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

    bool imagecopyresized (resource $dst_image, resource $src_image, int $dst_x, int $dst_y, int $src_x, int $src_y, int $dst_w, int $dst_h, int $src_w, int $src_h)

Вот именно эта функция поможет нам сделать из большой фотографии ее уменьшенную копию. Но эта функция также может и увеличивать фото, но имейте ввиду, что качество изображения при увеличении будет теряться.
$dst_image - ресурс-приемник
$src_image - ресурс-приемник
$dst_x и $dst_y - координаты левого верхнего угла куда будет скопирована копия изображения
$src_x и $src_y - координаты левого верхнего угла откуда будет скопирована копия изображения
$dst_w и $dst_h - ширина и высота будущего изображения
$src_w и $src_h - ширина и высота текущего изображения из которого делается новое

В самом методе классы resize() мы делаем две ветки, первый идет на построение пропорционального изображения, второй не пропорционального.

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

    function waterMark ($fileName, $posInfo=array()) {
        if (($info = $this->_info($fileName, false))!==false and is_resource($this->im)) {
            $logo = $this->_load($fileName, $info['type']);
            
            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['alpha'])) // alpha    - прозрачность, от 0 до 100 (по умолчанию 60. 0 - прозрачно, 100 - без прозрачности)
                $posInfo['alpha'] = "60";

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

            for ($y=0; $y<$info['height']; $y++) {
                for ($x=0; $x<$info['width']; $x++) {
                    $colorIm     = imagecolorat($this->im,$posX+$x,$posY+$y);
                    $rgbIm         = imagecolorsforindex($this->im,$colorIm);
                    
                    $colorLogo     = imagecolorat($logo,$x,$y);
                    $rgbLogo     = imagecolorsforindex($logo,$colorLogo);
                    if ($rgbLogo['alpha']!==127) {
                        $colorNew = imagecolorallocatealpha($this->im, $rgbLogo["red"], $rgbLogo["green"], $rgbLogo["blue"], ceil(1.27*(100-$posInfo['alpha'])));
                        imagesetpixel($this->im, $posX+$x, $posY+$y, $colorNew);
                    }
                }
            }

        }
        else
            return false;
    }


Метод waterMark() принимает 2 параметра: имя файла и настройки наложения.

Попробуем применить это в действии, возьмем фотографию, например, Аватара:
Пример создание фотогалереи на PHP

и возьмем логотип, например, FF:
Пример создание фотогалереи на PHP
и выполним следующий код:

<?php
    include "image.php";
    $image = new Image("images/avatar.jpg");
    $image->waterMark("images/logo.png", array("alpha"=>30));
    $image->saveJpg("testWaterLogo.jpg");
?>


Получим вот такой результат:

Пример создание фотогалереи на PHP


 
Tweet


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

Комментарии


Friday, 19 February 2010 | 14:58:19 | Автор: Phoenix
Хм, интересно. Но вот тока что-то либо я не то сделал, либо...
В Денвере при загрузке выдаёт
Fatal error: Call to undefined method Image::waterMark() in Z:homelessonsphpwwwindex.php on line 33
33 строка это вот $image->waterMark("images/logo.png", array("alpha"=>30));
Обе картинки в папке images.
Код не менял и обе функции добавил в "класс для работы с изображениями в PHP".
Friday, 19 February 2010 | 15:31:48 | Автор: programmer
Phoenix, а Вы добавили в класс Image методы waterMark и resize которые описаны в этой статье?
Friday, 19 February 2010 | 15:53:36 | Автор: Phoenix
Да, конечно. И waterMark и resize добавлены в класс Images.
Friday, 19 February 2010 | 16:04:42 | Автор: programmer
Phoenix, добавлены непосредственно в класс Image (файл class/image.php)?
Friday, 19 February 2010 | 16:32:44 | Автор: Phoenix
Да, но только image.php у меня в корне.
И немного поэкспериментировал с методом научного тыка, и вместо
$image->waterMark("images/logo.png", array("alpha"=>30));
поставил
text("Просто текст под углом", array("size"=>16, "angle"=>45, "color"=>"#FF0000"));
И усё заработало. Получил картинку с надписью.
Friday, 19 February 2010 | 16:36:35 | Автор: programmer
Т.е. именно так?
text("Просто текст под углом", array("size"=>16, "angle"=>45, "color"=>"#FF0000"));


Тогда вообще не должно работать, ведь text() должен являться методом класса $image и вызываться как $image->text().

К ночи сегодня допишу статью по новой версии галереи, которую Вы можете уже посмотреть http://phpprogs.ru/test/photogallery/, где в админку был добавлен модуль атентификации
Friday, 19 February 2010 | 16:44:17 | Автор: Phoenix
Ой, копировал, а не посмотрел что захватил не всё. Вот что вставлено $image->text("Просто текст под углом", array("size"=>16, "angle"=>45, "color"=>"#FF0000"));

Странно конечно, но сделал следующее. Удалил из image.php методы waterMark и resize, а затем снова из прописал, и всё заработало.
Но есть вопрос ещё. Рядом с картинкой, вернее даже перед ней, выводятся цифры, например возле картинки с Аватаром стоят цифры 162:440. Что это за цифры, от куда они взялись? Причем цифры постоянно присутствует не зависимо от того выводим картинку на экран или нет.
Friday, 19 February 2010 | 23:04:51 | Автор: programmer
Phoenix,
По поводу удаления и добавления кода. Скорее всего Вы добавили в начале код двух методов вне класса Image, т.е. это были простые функции.
А цифры выводятся скорее всего какие-то проверочные, при тестировании наверное я забыл убрать
Friday, 19 February 2010 | 23:13:42 | Автор: Phoenix
Добавлял именно в класс, думаю просто глюк какой-то был в программе. Но это уже не важно, главное сейчас все правильно и работает. По вопросу цифр, где их искать?
Friday, 19 February 2010 | 23:44:01 | Автор: programmer
Ищите где-то echo
Добавить комментарий
Чтобы оставить комментарий, Вам необходимо зарегистрироваться или авторизироваться