Сервис для нанесения водяного знака своими руками на 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. Если будите менять папку, то следует учитывать пути в коде.

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

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

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

If you have found a spelling error, please, notify us by selecting that text and tap on selected text.

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

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

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