Статьи

Добавление текстовых водяных знаков с помощью Imagick

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

На момент написания этой статьи практически не было документации по PHP- документации Imagick API , хотя на веб-сайте ImageMagick можно найти множество примеров командной строки, поэтому мы и начнем. Преобразование кода командной строки из примеров в PHP — это просто утомительный вопрос поиска подходящих методов, которые выполняют те же функции.

Для моих примеров я буду использовать следующее изображение какого-то совершенно случайного красивого джентльмена.

Нанесение текста на изображение

Самый простой тип текстового водяного знака для создания — это наложение строки поверх изображения.

Пример командной строки:

  convert image.png -font Arial -pointsize 20 
     вытащить "гравитацию на юг
         заполните черным текстом 0,12 «Авторское право»
         заполните белым текстом 1,11 «Авторское право» 
     result.png 

И эквивалент PHP:

<?php // Create objects $image = new Imagick('image.png'); // Watermark text $text = 'Copyright'; // Create a new drawing palette $draw = new ImagickDraw(); // Set font properties $draw->setFont('Arial'); $draw->setFontSize(20); $draw->setFillColor('black'); // Position text at the bottom-right of the image $draw->setGravity(Imagick::GRAVITY_SOUTHEAST); // Draw text on the image $image->annotateImage($draw, 10, 12, 0, $text); // Draw text again slightly offset with a different color $draw->setFillColor('white'); $image->annotateImage($draw, 11, 11, 0, $text); // Set output image format $image->setImageFormat('png'); // Output the new image header('Content-type: image/png'); echo $image; 

Результат:

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

Прозрачный текст с использованием маски шрифта

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

Пример командной строки:

  convert -size 300x50 xc: grey30 -font Arial -pointsize 20 
     -гравитационный центр-розыгрыш "Заполнить grey70 текст 0,0 'Copyright'" 
     fgnd.png
 convert -size 300x50 xc: black -font Arial -pointsize 20 -Гравитационный центр 
     -сделать "заполнить белым текстом 1,1 'Copyright'
         текст 0,0 «Авторское право»
         заполните черным текстом -1, -1 «Авторское право» 
     + матовая маска.png
 составной -компонентный CopyOpacity mask.png fgnd.png stamp.png 
     mogrify -trim + repage stamp.png
 составная гравитация южная геометрия + 0 + 10 stamp.png image.png 
     result.png 

PHP эквивалент:

 <?php // Create objects $image = new Imagick('image.png'); $watermark = new Imagick(); $mask = new Imagick(); $draw = new ImagickDraw(); // Define dimensions $width = $image->getImageWidth(); $height = $image->getImageHeight(); // Create some palettes $watermark->newImage($width, $height, new ImagickPixel('grey30')); $mask->newImage($width, $height, new ImagickPixel('black')); // Watermark text $text = 'Copyright'; // Set font properties $draw->setFont('Arial'); $draw->setFontSize(20); $draw->setFillColor('grey70'); // Position text at the bottom right of the image $draw->setGravity(Imagick::GRAVITY_SOUTHEAST); // Draw text on the watermark palette $watermark->annotateImage($draw, 10, 12, 0, $text); // Draw text on the mask palette $draw->setFillColor('white'); $mask->annotateImage($draw, 11, 13, 0, $text); $mask->annotateImage($draw, 10, 12, 0, $text); $draw->setFillColor('black'); $mask->annotateImage($draw, 9, 11, 0, $text); // This is needed for the mask to work $mask->setImageMatte(false); // Apply mask to watermark $watermark->compositeImage($mask, Imagick::COMPOSITE_COPYOPACITY, 0, 0); // Overlay watermark on image $image->compositeImage($watermark, Imagick::COMPOSITE_DISSOLVE, 0, 0); // Set output image format $image->setImageFormat('png'); // Output the new image header('Content-type: image/png'); echo $image; 

Результат:

В этом примере создано несколько изображений. Первое изображение $watermark имеет $watermark серого, а второе изображение $mask использует чистый черный для частей, которые я хочу быть прозрачным, и белый для частей, которые я хочу сохранить. Когда я применяю маску, комбинируя изображения, любые оттенки серого, найденные в $mask в результате сглаживания, будут полупрозрачными и приведут к более гладким краям.

В версии кода для командной строки внешние края прозрачного изображения обрезаются до наложения водяного знака, но, как представляется, существует ошибка, которая не позволяет методу setGravity() сохранить положение, определенное setGravity() . Это в основном означает, что если бы я обрезал края, мой водяной знак потерял бы свое место в правом нижнем углу и был бы перемещен в верхнем левом углу. Чтобы обойти это глупое поведение, я создал свои палитры с теми же размерами, что и исходное изображение, поэтому отсечение не происходит.

Плиточный текст

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

Командная строка:

  конвертировать - размер 140x80 xc: нет - заполнить серым 
     -Gravity NorthWest -draw "текст 10,10 'Авторское право'" 
     -Gravity SouthEast-draw "text 5,15 'Copyright'" 
     Мифф: - | 
 композитный материал - image.png result.png 

PHP:

 <?php // Create objects $image = new Imagick('image.png'); $watermark = new Imagick(); // Watermark text $text = 'Copyright'; // Create a new drawing palette $draw = new ImagickDraw(); $watermark->newImage(140, 80, new ImagickPixel('none')); // Set font properties $draw->setFont('Arial'); $draw->setFillColor('grey'); $draw->setFillOpacity(.5); // Position text at the top left of the watermark $draw->setGravity(Imagick::GRAVITY_NORTHWEST); // Draw text on the watermark $watermark->annotateImage($draw, 10, 10, 0, $text); // Position text at the bottom right of the watermark $draw->setGravity(Imagick::GRAVITY_SOUTHEAST); // Draw text on the watermark $watermark->annotateImage($draw, 5, 15, 0, $text); // Repeatedly overlay watermark on image for ($w = 0; $w < $image->getImageWidth(); $w += 140) { for ($h = 0; $h < $image->getImageHeight(); $h += 80) { $image->compositeImage($watermark, Imagick::COMPOSITE_OVER, $w, $h); } } // Set output image format $image->setImageFormat('png'); // Output the new image header('Content-type: image/png'); echo $image; 

Результат:

Обратите внимание, что я установил прозрачность с помощью setFillOpacity() а не с помощью маски изображения.

Резюме

Для меня манипулирование изображениями в PHP стало одним из самых приятных аспектов языка, и я могу только надеяться, что Imagick будет включен в будущие версии. Если вы ищете способ внести свой вклад, я рекомендую вам преобразовать другие примеры командной строки в PHP, а затем опубликовать свои результаты в официальном руководстве по PHP, чтобы другие могли учиться и наслаждаться.

Изображение через Fotolia