Добавление водяного знака на изображение в PHP 8

Добавление водяного знака на изображение в PHP 8

Добавление водяного знака на изображение в PHP 8

Доброго времени суток! В примере ниже мы рассмотрим с Вами как можно добавить водяной знак на изображение
в PHP. В примере будем использовать библиотеку GD, поэтому она должна быть у Вас установлена. Также в примере
будем использовать версию PHP 8.1.

Класс Image — обертка над GdImage



<?php



declare(strict_types=1);



class Image

{

    private string $filename;

    private GdImage $image;

    private int $width;

    private int $height;

    private int $bits;

    private string $mimeType;





    /**

     * @throws Exception

     */

    public function __construct(string $filename)

    {

        // если расширение не загружено - бросаем исключение

        if (!extension_loaded('gd')) {

            throw new Exception('GD extension is not loaded');

        }





        if (file_exists($filename)) {

            $this->filename = $filename;



            $fileInfo = getImageSize($filename);



            if(!$fileInfo) {

                throw new Exception("Image file corrupted: $filename"); 

            }



            $this->width  = $fileInfo[0];

            $this->height = $fileInfo[1];

            $this->bits = $fileInfo['bits'] ?? '';

            $this->mimeType = $fileInfo['mime'] ?? '';



            // выражение match, добавленное в PHP 8, выполняет функции switch

            // создаем изображение из файла заданного формата

            $this->image = match ($this->mimeType) {

                'image/gif' => imageCreateFromGif($filename),

                'image/png' => imageCreateFromPng($filename),

                'image/jpeg' => imageCreateFromJpeg($filename),

                default => throw new Exception("Unrecognized image type: $filename"),

            };

        } else {

            throw new Exception("Could not load image $filename");

        }

    }





    public function getFile(): string

    {

        return $this->filename;

    }







    public function getImage(): GdImage

    {

        return $this->image;

    }





    public function getResource(): GdImage

    {

        return $this->image;

    }





    public function cleanResource(): void

    {

        imageDestroy($this->image);

    }





    public function getWidth(): int

    {

        return $this->width;

    }





    public function getHeight(): int

    {

        return $this->height;

    }





    public function getBits(): int

    {

        return $this->bits;

    }





    public function getMime(): string

    {

        return $this->mime;

    }





    public function __toString(): string

    {

        return "[Object Image({$this->getFile()}@{$this->getWidth()}x{$this->getHeight()})]";

    }

}





Класс ImageProcessor — принимает класс Image и ставит на нем водяной знак

<?php



declare(strict_types=1);





class ImageProcessor

{

    private Image $image;





    public function __construct(Image $image)

    {

        $this->image = $image;

    }



    /**

     * Сохраняет изображение в файл 

     * 

     * @throws Exception

     */

    public function save(string $file, int $quality = 90): bool

    {

        $isSaveSuccessfully = false;

        $info = pathinfo($file);

        $extension = strtolower($info['extension']);



        //print($extension);

        $image = $this->image->getResource();

        $is_resource = is_resource($image);



        $isSaveSuccessfully = match ($extension) {

            'jpeg', 'jpg' => imageJpeg($image, $file, $quality),

            'png' => imagePng($image, $file),

            'gif' => imageGif($image, $file),

            default => throw new Exception("Unrecognized output image format: $extension"),

        };



        imageDestroy($image);



        return $isSaveSuccessfully;

    }





    /**

     * Возвращает массив из двух точек - положение водяного знака на исходном изображении 

     * 

     * @param Image $watermark

     * @param WatermarkPosition $position

     * @return array<int, int>

     */

    private function getIntPosition(Image $watermark, WatermarkPosition $position): array

    {

        return match ($position) {

            WatermarkPosition::TopLeft => [0, 0],

            WatermarkPosition::TopCenter => [

                ($this->image->getWidth() - $watermark->getWidth()) / 2,

                0

            ],

            WatermarkPosition::TopRight => [

                $this->image->getWidth() - $watermark->getWidth(),

                0

            ],

            WatermarkPosition::MiddleLeft => [

                0,

                ($this->image->getHeight()->$watermark->getHeight()) / 2

            ],

            WatermarkPosition::MiddleCenter => [

                ($this->image->getWidth() - $watermark->getWidth()) / 2,

                ($this->image->getHeight() - $watermark->getHeight()) / 2

            ],

            WatermarkPosition::MiddleRight => [

                $this->image->getWidth() - $watermark->getWidth(),

                ($this->image->getHeight() - $watermark->getHeight()) / 2

            ],

            WatermarkPosition::BottomLeft => [

                0,

                $this->image->getHeight() - $watermark->getHeight()

            ],

            WatermarkPosition::BottomCenter => [

                ($this->image->getWidth() - $watermark->getWidth()) / 2,

                $this->image->getHeight() - $watermark->getHeight()

            ],

            WatermarkPosition::BottomRight => [

                $this->image->getWidth() - $watermark->getWidth(),

                $this->image->getHeight() - $watermark->getHeight()

            ]

        };

    }





    /**

     * Добавляет водяной знак на изображение с помощью функций библиотеки GD 

     * 

     * @param Image $watermark

     * @param WatermarkPosition $position

     * @return void

     * 

     */

    public function addWatermark(Image $watermark, WatermarkPosition $position = WatermarkPosition::BottomRight): void

    {

        [$watermarkX, $watermarkY] = $this->getIntPosition($watermark, $position);



        $image = $this->image->getResource();



        ImageAlphaBlending($image, true);

        ImageSaveAlpha($image, true);

        ImageCopy($image, $watermark->getImage(), intval($watermarkX), intval($watermarkY), 0, 0, $watermark->getWidth(), $watermark->getHeight());



        ImageDestroy($watermark->getImage());

        $this->image->setGdImage($image);

    }





}



Перечисление WatermarkPosition — описывает положения для водяного знака на исходном изображении



<?php



enum WatermarkPosition

{

    case TopLeft;

    case TopCenter;

    case TopRight;

    case MiddleLeft;

    case MiddleCenter;

    case MiddleRight;

    case BottomLeft;

    case BottomCenter;

    case BottomRight;

}





watermark.php — пример использования



<?php



spl_autoload_register(fn($class) => require_once __DIR__ . "/lib/$class.php");





$image1 = 'images/base_image.png';

$image2 = 'images/watermark.png';



try {

    $baseImage = new Image($image1);

    $watermarkImage = new Image($image2);



    $imageProcessor = new ImageProcessor($baseImage);

    $imageProcessor->addWatermark($watermarkImage, WatermarkPosition::BottomLeft);



    $current_time = time();

    $imageProcessor->save("./image_with_watermark_$current_time.jpg");





} catch (Exception $e) {

    print($e->getMessage());

}





Таким образом, с помощью PHP библиотеки GD можно ставить водяные знаки на изображении и не только!

Источник

НЕТ КОММЕНТАРИЕВ

Оставить комментарий