Сервис для нанесения водяного знака своими руками на PHP

На работе возникала необходимость нанесения водяного знака на техническое свидетельство. Водяной знак представлял собой обычно 4-5 строк текста.

В начале я данную задачу делал обычно при помощи графической программы Photoshop. Однако со временем надоело выполнять данную задачу в ручную и пришла идея написать готовый скрипт на PHP (тем более проблем с разворачиванием сервера не было, т.к. для разработки уже использовался локальный сервер). Задача написания скрипта оказалось простой и не сложной. Итак, приступим.

В начале необходимо создать вот такую структуру папок и файлов на вашем локальном сервере:

Структура файлов и папок

В папке fonts мы удобно поместили шрифт, используемый для написания текста водяного знака. Я использовал шрифт Moscow Sans Regular. Вы же можете воспользоваться любым своим шрифтом.

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

Папка source необходима для наших исходных изображений, на которые будет накладываться водяной знак. Кстати, я для своей задачи использовал 17 изображений, представляющих отсканированные страницы формата А4. Естественно можно помесить в нее как одно изображение, так хоть сотню. Просто увеличется время выполнения скрипта. Однако, не рекомендую слишком большое количество файлов.

В файле index.php мы разместим нашу форму, на которой будет возможность менять текст водяного знака, а также управлять размером шрифта и углом наклона водяного знака.

Форма для данных водяного знака

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

В файле create.php разместим сам код для наложения водяного знака на наши исходные изображения. В случае успеха будет сделано перенаправление на index.php и вывод сообщения об успехе.

Для оформления я использовал css-фреймворк bootstrap и собственный файл css-стилей.

Файл style.css

body {
    background-color: #222;
    color: #fff;
}
input[type=text]{
    border-radius: 0;
    width: 400px !important;
}
button.btn{
    border-radius: 0;
}
div.alert-success {
    margin-top: 10px;
    border-radius: 0;
    width: 400px;
}
.width100p {
    width: 100% !important;
}
.noresize {
    resize: none;
    border-radius: 0;
}

Файл index.php

<?php
session_start();

$text = [
  'Техническое свидетельство и Техническая оценка',
  'выданы: ООО "Организация"',
  'объект: ООО "Название объекта"',
  'по адресу: г. Название, ул. Название, д. 1'
];
?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Водяной знак для тех. свидетельства</title>
    <link rel="stylesheet" href="../css/bootstrap.min.css"/>
    <link rel="stylesheet" href="../css/style.css"/>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-sm-12">
            <br>
            <a href="/" class="btn btn-default">Назад</a>
        </div>
    </div>
    <div class="row">
        <div class="col-sm-12">
            <h3>Данные для водяного знака</h3>

            <? if ($_GET['result'] == 'success'){?>
            <div class="alert alert-success" role="alert">Водяной знак успешно наложен.</div>
            <?}?>

            <?
            if (!isset($_GET['result']) && $_GET['result'] != 'success') {
        unset($_SESSION['text']);
      }
      ?>

            <form method="post" action="create.php">
                <div class="form-group">
                    <label>Строка 1</label>
                    <input type="text" name="text[]" class="form-control" value="<?= isset($_SESSION['text']) ? htmlspecialchars($_SESSION['text'][0]) : htmlspecialchars($text[0]) ?>">
                </div>
                <div class="form-group">
                    <label>Строка 2</label>
                    <input type="text" name="text[]" class="form-control" value="<?= isset($_SESSION['text']) ? htmlspecialchars($_SESSION['text'][1]) : htmlspecialchars($text[1]) ?>">
                </div>
                <div class="form-group">
                    <label>Строка 3</label>
                    <input type="text" name="text[]" class="form-control" value="<?= isset($_SESSION['text']) ? htmlspecialchars($_SESSION['text'][2]) : htmlspecialchars($text[2]) ?>">
                </div>
                <div class="form-group">
                    <label>Строка 4</label>
                    <input type="text" name="text[]" class="form-control" value="<?= isset($_SESSION['text']) ? htmlspecialchars($_SESSION['text'][3]) : htmlspecialchars($text[3]) ?>">
                </div>
                <div class="form-group">
                    <label>Строка 5</label>
                    <input type="text" name="text[]" class="form-control" value="<?= isset($_SESSION['text']) ? htmlspecialchars($_SESSION['text'][4]) : htmlspecialchars($text[4]) ?>">
                </div>

                <div class="form-group">
                    <label>Размер шрифта</label>
                    <input type="text" name="sizeFont" class="form-control" value="54" style="width: 60px !important;">
                </div>
                <div class="form-group">
                    <label>Угол наклона вод. знака</label>
                    <input type="text" name="angleText" class="form-control" value="30" style="width: 60px !important;">
                </div>

                <button type="submit" class="btn btn-success">Наложить водяной знак</button>
                <? if (isset($_SESSION['text'])) {?>
                    <a href="/watermark/" class="btn btn-warning">Сбросить значения</a>
                <?}?>
            </form>
        </div>
    </div>
</div>
</body>
</html>

Особых комментариев по данному коду не стану делать. Все итак довольно просто и понятно. Переменная $text является массивом всех строк для водяного знака, т.е. каждая новая строка — это новый элемент массива $text.

А вот и сам более интересный файл create.php.

<?php

session_start();

/**
 * Создание водяного знака
 */
if ($_POST){
  $arrText = array_diff($_POST['text'], ['']); // Из массива отсеиваем пустые строки
  $sizeFont = (int)$_POST['sizeFont'];
  $angleText = (int)$_POST['angleText'];

  $fontPath = dirname(__FILE__) . '/fonts/MoscowSansRegular.ttf';
  $sourcePath = dirname(__FILE__) . '/source/';
  $outputPath = dirname(__FILE__) . '/output/';

  /**
   * @param     $img Идентификатор изображения, на которое добавляется водяной знак
   * @param     $text Текст надписи
   * @param     $font Имя файла шрифта .ttf
   * @param int $r Цвет надписи в формате RGB
   * @param int $g Цвет надписи в формате RGB
   * @param int $b Цвет надписи в формате RGB
   * @param int $alpha Уровень прозрачности от 0 до 128
   * @return mixed
   */
  function addWatermark($img, $text, $font, $r = 128, $g = 128, $b = 128, $alpha = 100)
  {
    if(!is_array($text)) return false;

    $width = imagesx($img);
    $height = imagesy($img);
    $angle = 30;

    $c = imagecolorallocatealpha($img, $r, $g, $b, $alpha);
    $size = 54;

    $offset = 100; // Смещение между строками для оси Y

    // Нанесение текста из массива со смещением по оси Y
    for($i=0;$i<count($text);$i++){
      $box  = imagettfbbox ($size, $angle, $font, $text[$i]);
      $x = $width/2 - abs($box[4] - $box[0])/2;
      $y = ($height/2 + abs($box[5] - $box[1])/2) + $offset*$i;
      imagettftext($img, $size, $angle, $x, $y, $c, $font, $text[$i]);
    }

    return $img;
  }

  $allFilenames = glob($sourcePath . '*.jpg');
  $countFiles = count($allFilenames);

  for($i=0;$i<$countFiles;$i++){
    $img = imagecreatefromjpeg($allFilenames[$i]);
    $image = addWatermark($img, $arrText, $fontPath, 72, 72, 72, 60);
    imageJPEG($image, $outputPath . basename($allFilenames[$i]));
    imagedestroy($image);
  }

  $_SESSION['text'] = $arrText;

  header('Location: /watermark/?result=success');
}

Код максимально снабжен комментариями, что сделает его понимание более простым.

Внимание. Для правильной работы необходимо добавить шрифт в папку fonts и изменить его имя в переменной $fontPath. В папку source необходимо добавить хотя бы одно исходное изображение (учитываются только файлы с расширением JPG).

Еще одна пометка — все файлы я располагал в отдельной папке watermark. Если будите менять папку, то следует учитывать пути в коде.

Таким образом, за короткий промежуток времени набросал небольшой полезный скрипт, который сэкономит время при создании водяного знака в несколько строк.

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

Спасибо за внимание. Если возникли вопросы, пишите.

 

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

SoladieM

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

Добавить комментарий

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: