-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 59e9bdb
Showing
9 changed files
with
352 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
* text=auto eol=lf | ||
/.gitattributes export-ignore | ||
/.gitignore export-ignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2023 Jirka Daněk | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
Watermark | ||
######### | ||
|
||
Watermarks for uploaded images. | ||
|
||
.. contents:: | ||
|
||
Requirements | ||
************ | ||
|
||
- SunLight CMS 8 | ||
|
||
Installation | ||
************ | ||
|
||
:: | ||
|
||
Copy the folder 'plugins' and its contents to the root directory | ||
|
||
or | ||
|
||
:: | ||
|
||
Installation via administration: 'Administration > Plugins > Upload new plugins' | ||
|
||
Configuration | ||
************* | ||
|
||
The path to the watermark file can be found in the plugin settings. The default path is `upload/watermark.png` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
|
||
namespace SunlightExtend\Watermark; | ||
|
||
use Sunlight\Plugin\Action\ConfigAction as BaseConfigAction; | ||
use Sunlight\Util\Form; | ||
|
||
class ConfigAction extends BaseConfigAction | ||
{ | ||
protected function getFields(): array | ||
{ | ||
$config = $this->plugin->getConfig(); | ||
$positions = Watermark::getPositions(); | ||
|
||
return [ | ||
'watermark_file' => [ | ||
'label' => _lang('watermark.config.watermark_file'), | ||
'input' => '<input type="text" name="config[watermark_file]" ' . Form::restorePostValue('config[watermark_file]', $config['watermark_file']) . ' class="inputmedium">', | ||
'type' => 'text', | ||
], | ||
'watermark_position' => [ | ||
'label' => _lang('watermark.config.watermark_position'), | ||
'input' => _buffer(function () use ($config, $positions) { ?> | ||
<select name="config[watermark_position]" class="inputmedium"> | ||
<?php foreach ($positions as $position) : ?> | ||
<option value="<?= $position ?>"<?= $config['watermark_position'] == $position ? ' selected' : '' ?>><?= _lang('watermark.config.pos.' . $position) ?></option> | ||
<?php endforeach; ?> | ||
</select> | ||
<?php }), | ||
'type' => 'text', | ||
], | ||
'resize_large_watermark' => [ | ||
'label' => _lang('watermark.config.resize_large_watermark'), | ||
'input' => '<input type="checkbox" name="config[resize_large_watermark]" ' . Form::restorePostValue('config[resize_large_watermark]', $config['resize_large_watermark']) . '>', | ||
'type' => 'checkbox', | ||
] | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
<?php | ||
|
||
namespace SunlightExtend\Watermark; | ||
|
||
use Sunlight\Image\Image; | ||
|
||
class Watermark | ||
{ | ||
public const POS_TOP_CENTER = 'top-center'; | ||
public const POS_TOP_LEFT = 'top-left'; | ||
public const POS_TOP_RIGHT = 'top-right'; | ||
public const POS_CENTER = 'center'; | ||
public const POS_CENTER_LEFT = 'center-left'; | ||
public const POS_CENTER_RIGHT = 'center-right'; | ||
public const POS_BOTTOM_CENTER = 'bottom-center'; | ||
public const POS_BOTTOM_LEFT = 'bottom-left'; | ||
public const POS_BOTTOM_RIGHT = 'bottom-right'; | ||
|
||
/** @var Image */ | ||
private $source; | ||
/** @var Image */ | ||
private $watermark; | ||
/** @var bool */ | ||
private $resizeLargeWatermark = false; | ||
|
||
public function __construct(Image $source, Image $watermark) | ||
{ | ||
$this->source = $source; | ||
$this->watermark = $watermark; | ||
} | ||
|
||
public static function getPositions(): array | ||
{ | ||
return [ | ||
self::POS_TOP_CENTER, | ||
self::POS_TOP_LEFT, | ||
self::POS_TOP_RIGHT, | ||
self::POS_CENTER, | ||
self::POS_CENTER_LEFT, | ||
self::POS_CENTER_RIGHT, | ||
self::POS_BOTTOM_CENTER, | ||
self::POS_BOTTOM_LEFT, | ||
self::POS_BOTTOM_RIGHT, | ||
]; | ||
} | ||
|
||
private function getPositionCoordinate(Image $source, Image $watermark, string $position): array | ||
{ | ||
// default | ||
$positionX = 0; | ||
$positionY = 0; | ||
|
||
switch ($position) { | ||
case self::POS_TOP_CENTER: | ||
$positionX = ($source->width / 2) - ($watermark->width / 2); | ||
// $positionY = 0; | ||
break; | ||
case self::POS_TOP_RIGHT: | ||
$positionX = $source->width - $watermark->width; | ||
// $positionY = 0; | ||
break; | ||
case self::POS_CENTER: | ||
$positionX = ($source->width / 2) - ($watermark->width / 2); | ||
$positionY = ($source->height / 2) - ($watermark->height / 2); | ||
break; | ||
case self::POS_CENTER_LEFT: | ||
// $positionX = 0; | ||
$positionY = ($source->height / 2) - ($watermark->height / 2); | ||
break; | ||
case self::POS_CENTER_RIGHT: | ||
$positionX = $source->width - $watermark->width; | ||
$positionY = ($source->height / 2) - ($watermark->height / 2); | ||
break; | ||
case self::POS_BOTTOM_CENTER: | ||
$positionX = ($source->width / 2) - ($watermark->width / 2); | ||
$positionY = $source->height - $watermark->height; | ||
break; | ||
case self::POS_BOTTOM_LEFT: | ||
// $positionX = 0; | ||
$positionY = $source->height - $watermark->height; | ||
break; | ||
case self::POS_BOTTOM_RIGHT: | ||
$positionX = ($source->width - $watermark->width) - 5; | ||
$positionY = ($source->height - $watermark->height) - 5; | ||
break; | ||
case self::POS_TOP_LEFT: | ||
default: | ||
// $positionX = 0; | ||
// $positionY = 0; | ||
break; | ||
} | ||
|
||
return ['x' => (int)$positionX, 'y' => (int)$positionY]; | ||
} | ||
|
||
public function setResizeLargeWatermark(bool $resizeLargeWatermark): void | ||
{ | ||
$this->resizeLargeWatermark = $resizeLargeWatermark; | ||
} | ||
|
||
/** | ||
* Supported parameters: | ||
* | ||
* - top-center - position of the watermark at the top centre | ||
* - top-left - position of the watermark at the top left | ||
* - top-right - position of the watermark at the top right | ||
* - center - position of the watermark centered | ||
* - center-left - position of the watermark at the center left | ||
* - center-right - position of the watermark at the center right | ||
* - bottom-center - position of the watermark at the bottom center | ||
* - bottom-left - position of the watermark at the bottom left | ||
* - bottom-right - position of the watermark at the bottom right | ||
*/ | ||
public function apply(string $position = self::POS_CENTER): void | ||
{ | ||
imagealphablending($this->source->resource, true); | ||
imagesavealpha($this->source->resource, true); | ||
|
||
$watermark = $this->resizeLargeWatermark(); | ||
|
||
$watermarkPositions = $this->getPositionCoordinate( | ||
$this->source, | ||
$watermark, | ||
$position | ||
); | ||
|
||
// image merge | ||
imagecopy( | ||
$this->source->resource, | ||
$watermark->resource, | ||
$watermarkPositions['x'], | ||
$watermarkPositions['y'], | ||
0, | ||
0, | ||
$watermark->width, | ||
$watermark->height | ||
); | ||
} | ||
|
||
/** | ||
* Reduce the watermark to one third of the original image | ||
* @return Image | ||
*/ | ||
private function resizeLargeWatermark(): Image | ||
{ | ||
$sourceWidth = $this->source->width; | ||
$sourceHeight = $this->source->height; | ||
$watermarkWidth = $this->watermark->width; | ||
$watermarkHeight = $this->watermark->height; | ||
|
||
// compare the dimensions and shrink the watermark if it is larger | ||
if ( | ||
$this->resizeLargeWatermark | ||
&& ($watermarkWidth > $sourceWidth || $watermarkHeight > $sourceHeight) | ||
) { | ||
// determine whether the watermark is portrait or landscape | ||
if ($watermarkWidth > $watermarkHeight) { | ||
$newWidth = (int)($sourceWidth / 3); | ||
$newHeight = (int)($watermarkHeight * ($newWidth / $watermarkWidth)); | ||
} else { | ||
$newHeight = (int)($sourceHeight / 3); | ||
$newWidth = (int)($watermarkWidth * ($newHeight / $watermarkHeight)); | ||
} | ||
|
||
// create a new watermark with a modified size | ||
$newWatermark = imagecreatetruecolor($newWidth, $newHeight); | ||
|
||
// transparent color | ||
imagesavealpha($newWatermark, true); | ||
$transparentColor = imagecolorallocatealpha($newWatermark, 0, 0, 0, 127); | ||
imagefill($newWatermark, 0, 0, $transparentColor); | ||
|
||
// resize | ||
imagecopyresampled($newWatermark, $this->watermark->resource, 0, 0, 0, 0, $newWidth, $newHeight, $watermarkWidth, $watermarkHeight); | ||
|
||
return new Image($newWatermark, $newWidth, $newHeight); | ||
} | ||
// return original watermark | ||
return $this->watermark; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
use Sunlight\Image\ImageLoader; | ||
use SunlightExtend\Watermark\Watermark; | ||
|
||
return function (array $args) { | ||
if ($args['options']['resize']['w'] >= 500 && $args['options']['resize']['h'] >= 100) { | ||
|
||
$watermarkFile = SL_ROOT . $this->getConfig()['watermark_file']; | ||
if (!file_exists($watermarkFile)) { | ||
return; | ||
} | ||
|
||
$watermark = new Watermark($args['image'], ImageLoader::load($watermarkFile)); | ||
if ($this->getConfig()['resize_large_watermark']) { | ||
$watermark->setResizeLargeWatermark(true); | ||
} | ||
$watermark->apply($this->getConfig()['watermark_position']); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
return [ | ||
'config.watermark_file' => 'Cesta k souboru vodoznaku', | ||
'config.watermark_position' => 'Pozice', | ||
'config.resize_large_watermark' => 'Zmenšit vodoznak<br><small>pokud je vetší než originální obrázek</small>', | ||
'config.pos.top-center' => 'Nahoře uprostřed', | ||
'config.pos.top-left' => 'Nahoře vlevo', | ||
'config.pos.top-right' => 'Nahoře vpravo', | ||
'config.pos.center' => 'Uprostřed', | ||
'config.pos.center-left' => 'Uprostřed vlevo', | ||
'config.pos.center-right' => 'Uprostřed vpravo', | ||
'config.pos.bottom-center' => 'Dole uprostřed', | ||
'config.pos.bottom-left' => 'Dole vlevo', | ||
'config.pos.bottom-right' => 'Dole vpravo', | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
return [ | ||
'config.watermark_file' => 'Watermark file path', | ||
'config.watermark_position' => 'Watermark position', | ||
'config.resize_large_watermark' => 'Shrink the watermark<br><small>if the watermark is larger than the original image</small>', | ||
'config.pos.top-center' => 'Top center', | ||
'config.pos.top-left' => 'Top left', | ||
'config.pos.top-right' => 'Top right', | ||
'config.pos.center' => 'Center', | ||
'config.pos.center-left' => 'Center left', | ||
'config.pos.center-right' => 'Center right', | ||
'config.pos.bottom-center' => 'Bottom center', | ||
'config.pos.bottom-left' => 'Bottom left', | ||
'config.pos.bottom-right' => 'Bottom right', | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"$schema": "../../../system/schema/extend.json", | ||
"name": "Watermark", | ||
"description": "Watermarks for uploaded images", | ||
"version": "1.0.0", | ||
"authors": [ | ||
{"name": "Friends of Sunlight CMS", "url": "https://github.com/friends-of-sunlight-cms/"} | ||
], | ||
"environment": { | ||
"system": "^8.0" | ||
}, | ||
"config_defaults": { | ||
"watermark_file": "upload/watermark.png", | ||
"watermark_position": "center", | ||
"resize_large_watermark": true | ||
}, | ||
"actions": { | ||
"config": "ConfigAction" | ||
}, | ||
"langs": { | ||
"watermark": "lang" | ||
}, | ||
"events": [ | ||
{"event": "image.process.after", "script": "event/watermark.php"} | ||
] | ||
} |