View source
<?php
namespace Drupal\basic_watermark\Plugin\ImageToolkit\Operation\gd;
use Drupal\system\Plugin\ImageToolkit\Operation\gd\GDImageToolkitOperationBase;
class AddWatermark extends GDImageToolkitOperationBase {
protected function arguments() {
return [
'watermark_path' => [
'description' => 'The path to the watermark image',
],
'apply_type' => [
'description' => 'How to apply the watermark, repeat until it covers the whole image or once',
],
'position' => [
'description' => 'Where to put the watermark, ex: top-left, center, bottom-right',
],
'margins' => [
'description' => 'Empty area to keep around the watermark in pixels',
],
];
}
protected function validateArguments(array $arguments) {
$path = DRUPAL_ROOT . $arguments['watermark_path'];
if (!file_exists($path) || !getimagesize($path)) {
throw new \InvalidArgumentException("Invalid image ('{$arguments['watermark_path']}')");
}
return $arguments;
}
protected function execute(array $arguments) {
$image_resource = $this
->getToolkit()
->getResource();
$watermark_filepath = DRUPAL_ROOT . $arguments['watermark_path'];
$watermark_image = imagecreatefrompng($watermark_filepath);
$image['width'] = imagesx($image_resource);
$image['height'] = imagesy($image_resource);
$watermark = $this
->scaleWatermark($watermark_image, $image, $arguments['margins']);
$margins = $this
->getMargins($image, $watermark, $arguments['position'], $arguments['margins']);
$temp_resource = $this
->getToolkit()
->getResource();
switch ($arguments['apply_type']) {
case 'repeat':
$start_x = $arguments['margins']['left'];
for ($i = 0; $i < $image['width'] / $watermark['width'] + 1; $i++) {
$start_y = $arguments['margins']['top'];
for ($j = 0; $j < $image['height'] / $watermark['height'] + 1; $j++) {
$resource = imagecopy($temp_resource, $watermark['image'], $start_x, $start_y, 0, 0, min($watermark['width'], $image['width'] - $start_x), min($watermark['height'], $image['height'] - $start_y));
if (!$resource) {
$this
->getToolkit()
->setResource($image_resource);
return FALSE;
}
$start_y += $arguments['margins']['top'] + $watermark['height'];
}
$start_x += $arguments['margins']['left'] + $watermark['width'];
}
break;
case 'once':
$resource = imagecopy($temp_resource, $watermark['image'], $margins['x'], $margins['y'], 0, 0, $watermark['width'], $watermark['height']);
if (!$resource) {
$this
->getToolkit()
->setResource($image_resource);
return FALSE;
}
break;
default:
return FALSE;
}
$this
->getToolkit()
->setResource(TRUE);
imagedestroy($image_resource);
return TRUE;
}
private function scaleWatermark($watermark_image, array $image, array &$margins) {
$watermark['width'] = imagesx($watermark_image);
$watermark['height'] = imagesy($watermark_image);
if ($margins['left'] + $margins['right'] >= $image['width']) {
$margins['left'] = 0;
$margins['right'] = 0;
}
if ($margins['top'] + $margins['bottom'] >= $image['height']) {
$margins['top'] = 0;
$margins['bottom'] = 0;
}
if ($watermark['width'] + $margins['left'] + $margins['right'] > $image['width']) {
$watermark['width'] = $image['width'] - $margins['left'] - $margins['right'];
$watermark_image = imagescale($watermark_image, $watermark['width']);
$watermark['height'] = imagesy($watermark_image);
}
if ($watermark['height'] + $margins['top'] + $margins['bottom'] > $image['height']) {
$watermark['height'] = $image['height'] - $margins['top'] - $margins['bottom'];
$watermark['width'] = $watermark['height'] * (imagesx($watermark_image) / imagesy($watermark_image));
$watermark_image = imagescale($watermark_image, $watermark['width'], $watermark['height']);
}
return [
'image' => $watermark_image,
'width' => $watermark['width'],
'height' => $watermark['height'],
];
}
private function getMargins(array $image, array $watermark, string $position, array $margins) {
switch ($position) {
case 'left-top':
return [
'x' => $margins['left'],
'y' => $margins['top'],
];
case 'center-top':
return [
'x' => $image['width'] / 2 - $watermark['width'] / 2,
'y' => $margins['top'],
];
case 'right-top':
return [
'x' => $image['width'] - $watermark['width'] - $margins['left'],
'y' => $margins['top'],
];
case 'left-center':
return [
'x' => $margins['left'],
'y' => $image['height'] / 2 - $watermark['height'] / 2,
];
case 'center-center':
return [
'x' => $image['width'] / 2 - $watermark['width'] / 2,
'y' => $image['height'] / 2 - $watermark['height'] / 2,
];
case 'right-center':
return [
'x' => $image['width'] - $watermark['width'] - $margins['left'],
'y' => $image['height'] / 2 - $watermark['height'] / 2,
];
case 'left-bottom':
return [
'x' => $margins['left'],
'y' => $image['height'] - $watermark['height'] - $margins['top'],
];
case 'center-bottom':
return [
'x' => $image['width'] / 2 - $watermark['width'] / 2,
'y' => $image['height'] - $watermark['height'] - $margins['top'],
];
case 'right-bottom':
return [
'x' => $image['width'] - $watermark['width'] - $margins['left'],
'y' => $image['height'] - $watermark['height'] - $margins['top'],
];
default:
return [
'x' => $margins['left'],
'y' => $margins['top'],
];
}
}
}