Skip to content

Commit b7bde01

Browse files
committed
Watermarking with Image done. Repeating/Tile feature working.
1 parent 877097e commit b7bde01

File tree

5 files changed

+94
-16
lines changed

5 files changed

+94
-16
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
# PHPWatermark
22

3-
Add Watermark on images using PHP and [ImageMagick](http://www.imagemagick.org)
3+
Add Watermark on images using PHP and [ImageMagick](http://www.imagemagick.org)
4+
5+
### Pre-requisite
6+
7+
- PHP (version 5.6 or higher)
8+
- [ImageMagick](http://www.imagemagick.org)
9+
10+
11+
412
---
513

614
> "This is the Book about which there is no doubt, a guidance for those conscious of Allah" - [Al-Quran](http://quran.com)

examples/example.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,16 @@
1313

1414
$text = "ajaxray.com";
1515
$watermark->withText($text, __DIR__ . '/img/result_simple.jpg');
16-
echo $watermark->buildTextMarkCommand($text, __DIR__ . 'img/result_simple.jpg');
16+
// echo $watermark->buildTextMarkCommand($text, __DIR__ . 'img/result_simple.jpg');
17+
18+
$watermark->setTiled()->setTileSize(200, 150);
19+
$watermark->setFontSize(24);
20+
$watermark->withText($text, __DIR__ . '/img/result_tiled.jpg');
21+
// echo $watermark->buildTextMarkCommand($text, __DIR__ . 'img/result_tiled.jpg'). PHP_EOL;
22+
23+
// Watermarking with image
24+
$imgMark = new Watermark(__DIR__ . '/img/mountain.jpg');
25+
$imgMark->setPosition(Watermark::POSITION_TOP_RIGHT);
26+
$imgMark->setOffset(50, 50);
27+
$imgMark->setOpacity(.3);
28+
$imgMark->withImage(__DIR__ . '/img/php.png', __DIR__ . '/img/result_logo.jpg');

examples/img/logo.png

-10.4 KB
Binary file not shown.

examples/img/php.png

6.09 KB
Loading

src/Ajaxray/PHPWatermark/Watermark.php

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
namespace Ajaxray\PHPWatermark;
1010

1111
// https://www.sitepoint.com/adding-text-watermarks-with-imagick/
12-
// https://www.sitepoint.com/watermarking-images/
12+
// http://www.imagemagick.org/Usage/annotating/#watermarking
1313

1414
class Watermark
1515
{
@@ -26,14 +26,17 @@ class Watermark
2626

2727

2828
// @TODO : Option to change style
29-
const PRINT_STYLE_DARK = 1;
30-
const PRINT_STYLE_LIGHT = 2;
31-
const PRINT_STYLE_BEVEL = 3;
29+
const IMG_STYLE_COLORLESS = 1;
30+
const IMG_STYLE_DISSOLVE = 2;
31+
const TEXT_STYLE_DARK = 1;
32+
const TEXT_STYLE_LIGHT = 2;
33+
const TEXT_STYLE_BEVEL = 3;
3234

3335
private $position = 'Center';
34-
private $offsetX = 5;
35-
private $offsetY = 5;
36+
private $offsetX = 0;
37+
private $offsetY = 0;
3638
private $tiled = false;
39+
private $tileSize = ['100', '100'];
3740

3841
/**
3942
* Font name. Should be one of the list displayed by `convert -list font` command
@@ -44,7 +47,6 @@ class Watermark
4447
private $fontSize = 12;
4548
private $opacity = 0.4;
4649
private $rotate = 0;
47-
private $style = self::PRINT_STYLE_BEVEL;
4850
private $source;
4951

5052
/**
@@ -58,19 +60,32 @@ public function __construct($source)
5860
return $this;
5961
}
6062

61-
public function withText($text, $destination)
63+
public function withText($text, $writeTo = null)
6264
{
65+
$destination = $writeTo ?: $this->source;
6366
$this->ensureExists($this->source);
64-
$this->ensureWritable(dirname($destination));
67+
$this->ensureWritable(($writeTo ? dirname($destination) : $destination));
6568

6669
exec($this->buildTextMarkCommand($text, $destination), $output, $returnCode);
6770
return (empty($output) && $returnCode == 0);
6871
}
6972

73+
public function withImage($marker, $writeTo = null)
74+
{
75+
$destination = $writeTo ?: $this->source;
76+
$this->ensureExists($this->source);
77+
$this->ensureExists($marker);
78+
$this->ensureWritable(($writeTo ? dirname($destination) : $destination));
79+
80+
exec($this->buildImageMarkCommand($marker, $destination), $output, $returnCode);
81+
return (empty($output) && $returnCode == 0);
82+
}
83+
7084
public function buildTextMarkCommand($text, $destination)
7185
{
72-
$text = escapeshellarg($text);
86+
$source = $this->getSource();
7387
$destination = escapeshellarg($destination);
88+
$text = escapeshellarg($text);
7489

7590
$anchor = 'gravity '. $this->getPosition();
7691
$rotate = ($this->getRotate() == '0')? '' : "rotate {$this->getRotate()}";
@@ -83,16 +98,38 @@ public function buildTextMarkCommand($text, $destination)
8398
$offsetLight = "{$offset[0]},{$offset[1]}";
8499
$offsetDark = ($offset[0] + 1) .','. ($offset[1] + 1);
85100

101+
$draw = " -draw \"$rotate $anchor $colorLight text $offsetLight $text $colorDark text $offsetDark $text \" ";
102+
103+
// @TODO : Fix issue with single quote
86104
if($this->isTiled()) {
87-
$command = "convert -size 140x80 xc:none $font -$colorLight -$anchor -draw \"$rotate text 10,10 $text\" miff:- ";
88-
$command .= " | composite -tile - {$this->source} $destination";
105+
$size = "-size ". implode('x', $this->getTileSize());
106+
$command = "convert $size xc:none $font -$anchor $draw miff:- ";
107+
$command .= " | composite -tile - $source $destination";
89108
} else {
90-
$command = "convert {$this->getSource()} $font -draw \"$rotate $anchor $colorLight text $offsetLight $text $colorDark text $offsetDark $text\" $destination";
109+
$command = "convert $source $font $draw $destination";
91110
}
92111

93112
return $command;
94113
}
95114

115+
public function buildImageMarkCommand($marker, $destination)
116+
{
117+
$source = $this->getSource();
118+
$destination = escapeshellarg($destination);
119+
$marker = escapeshellarg($marker);
120+
121+
$anchor = 'gravity '. $this->getPosition();
122+
$rotate = ($this->getRotate() == '0')? '' : "rotate {$this->getRotate()}";
123+
124+
$offsetArr = $this->getOffset();
125+
$offset = "geometry +{$offsetArr[0]}+{$offsetArr[1]}";
126+
$tile = $this->isTiled() ? '-tile' : '';
127+
//$opacity = 'dissolve '. ($this->getOpacity() * 100) .'%';
128+
$opacity = 'watermark '. ($this->getOpacity() * 100);
129+
130+
// @TODO : Gap/offset between image tiles
131+
return "composite -$anchor -$offset -$rotate -$opacity $tile $marker $source $destination";
132+
}
96133

97134
private function ensureExists($filePath)
98135
{
@@ -106,7 +143,7 @@ private function ensureExists($filePath)
106143
private function ensureWritable($dirPath)
107144
{
108145
if (! is_writable($dirPath)) {
109-
$message = "The specified destination directory $dirPath is not writable!";
146+
$message = "The specified destination $dirPath is not writable!";
110147
throw new \RuntimeException($message);
111148
// @TODO : Create DestNotWritableException
112149
}
@@ -192,6 +229,27 @@ public function setTiled($tiled = true)
192229
return $this;
193230
}
194231

232+
/**
233+
* @param $width
234+
* @param $height
235+
*
236+
* @return Watermark
237+
*/
238+
public function setTileSize($width, $height)
239+
{
240+
$this->tileSize = [intval($width), intval($height)];
241+
242+
return $this;
243+
}
244+
245+
/**
246+
* @return array
247+
*/
248+
public function getTileSize()
249+
{
250+
return $this->tileSize;
251+
}
252+
195253
/**
196254
* @return string
197255
*/

0 commit comments

Comments
 (0)