123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- <?php
- /**
- * elFinder Plugin Watermark
- * Print watermark on file upload.
- * ex. binding, configure on connector options
- * $opts = array(
- * 'bind' => array(
- * 'upload.presave' => array(
- * 'Plugin.Watermark.onUpLoadPreSave'
- * )
- * ),
- * // global configure (optional)
- * 'plugin' => array(
- * 'Watermark' => array(
- * 'enable' => true, // For control by volume driver
- * 'source' => 'logo.png', // Path to Water mark image
- * 'ratio' => 0.2, // Ratio to original image (ratio > 0 and ratio <= 1)
- * 'position' => 'RB', // Position L(eft)/C(enter)/R(ight) and T(op)/M(edium)/B(ottom)
- * 'marginX' => 5, // Margin horizontal pixel
- * 'marginY' => 5, // Margin vertical pixel
- * 'quality' => 95, // JPEG image save quality
- * 'transparency' => 70, // Water mark image transparency ( other than PNG )
- * 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
- * 'targetMinPixel' => 200, // Target image minimum pixel size
- * 'interlace' => IMG_GIF|IMG_JPG, // Set interlacebit image formats ( bit-field )
- * 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
- * // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
- * // In case of using any key, specify it as an array
- * 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
- * // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
- * // In case of using any key, specify it as an array
- * )
- * ),
- * // each volume configure (optional)
- * 'roots' => array(
- * array(
- * 'driver' => 'LocalFileSystem',
- * 'path' => '/path/to/files/',
- * 'URL' => 'http://localhost/to/files/'
- * 'plugin' => array(
- * 'Watermark' => array(
- * 'enable' => true, // For control by volume driver
- * 'source' => 'logo.png', // Path to Water mark image
- * 'ratio' => 0.2, // Ratio to original image (ratio > 0 and ratio <= 1)
- * 'position' => 'RB', // Position L(eft)/C(enter)/R(ight) and T(op)/M(edium)/B(ottom)
- * 'marginX' => 5, // Margin horizontal pixel
- * 'marginY' => 5, // Margin vertical pixel
- * 'quality' => 95, // JPEG image save quality
- * 'transparency' => 70, // Water mark image transparency ( other than PNG )
- * 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field )
- * 'targetMinPixel' => 200, // Target image minimum pixel size
- * 'interlace' => IMG_GIF|IMG_JPG, // Set interlacebit image formats ( bit-field )
- * 'offDropWith' => null, // Enabled by default. To disable it if it is dropped with pressing the meta key
- * // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
- * // In case of using any key, specify it as an array
- * 'onDropWith' => null // Disabled by default. To enable it if it is dropped with pressing the meta key
- * // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
- * // In case of using any key, specify it as an array
- * )
- * )
- * )
- * )
- * );
- *
- * @package elfinder
- * @author Naoki Sawada
- * @license New BSD
- */
- class elFinderPluginWatermark extends elFinderPlugin
- {
- private $watermarkImgInfo = null;
- public function __construct($opts)
- {
- $defaults = array(
- 'enable' => true, // For control by volume driver
- 'source' => 'logo.png', // Path to Water mark image
- 'ratio' => 0.2, // Ratio to original image (ratio > 0 and ratio <= 1)
- 'position' => 'RB', // Position L(eft)/C(enter)/R(ight) and T(op)/M(edium)/B(ottom)
- 'marginX' => 5, // Margin horizontal pixel
- 'marginY' => 5, // Margin vertical pixel
- 'quality' => 95, // JPEG image save quality
- 'transparency' => 70, // Water mark image transparency ( other than PNG )
- 'targetType' => IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP, // Target image formats ( bit-field )
- 'targetMinPixel' => 200, // Target image minimum pixel size
- 'interlace' => IMG_GIF | IMG_JPG, // Set interlacebit image formats ( bit-field )
- 'offDropWith' => null, // To disable it if it is dropped with pressing the meta key
- // Alt: 8, Ctrl: 4, Meta: 2, Shift: 1 - sum of each value
- // In case of using any key, specify it as an array
- 'marginRight' => 0, // Deprecated - marginX should be used
- 'marginBottom' => 0, // Deprecated - marginY should be used
- 'disableWithContentSaveId' => true // Disable on URL upload with post data "contentSaveId"
- );
- $this->opts = array_merge($defaults, $opts);
- }
- public function onUpLoadPreSave(&$thash, &$name, $src, $elfinder, $volume)
- {
- if (!$src) {
- return false;
- }
- $opts = $this->getCurrentOpts($volume);
- if (!$this->iaEnabled($opts, $elfinder)) {
- return false;
- }
- $imageType = null;
- $srcImgInfo = null;
- if (extension_loaded('fileinfo') && function_exists('mime_content_type')) {
- $mime = mime_content_type($src);
- if (substr($mime, 0, 5) !== 'image') {
- return false;
- }
- }
- if (extension_loaded('exif') && function_exists('exif_imagetype')) {
- $imageType = exif_imagetype($src);
- if ($imageType === false) {
- return false;
- }
- } else {
- $srcImgInfo = getimagesize($src);
- if ($srcImgInfo === false) {
- return false;
- }
- $imageType = $srcImgInfo[2];
- }
- // check target image type
- $imgTypes = array(
- IMAGETYPE_GIF => IMG_GIF,
- IMAGETYPE_JPEG => IMG_JPEG,
- IMAGETYPE_PNG => IMG_PNG,
- IMAGETYPE_BMP => IMG_WBMP,
- IMAGETYPE_WBMP => IMG_WBMP
- );
- if (!isset($imgTypes[$imageType]) || !($opts['targetType'] & $imgTypes[$imageType])) {
- return false;
- }
- // check Animation Gif
- if ($imageType === IMAGETYPE_GIF && elFinder::isAnimationGif($src)) {
- return false;
- }
- // check Animation Png
- if ($imageType === IMAGETYPE_PNG && elFinder::isAnimationPng($src)) {
- return false;
- }
- // check water mark image
- if (!file_exists($opts['source'])) {
- $opts['source'] = dirname(__FILE__) . "/" . $opts['source'];
- }
- if (is_readable($opts['source'])) {
- $watermarkImgInfo = getimagesize($opts['source']);
- if (!$watermarkImgInfo) {
- return false;
- }
- } else {
- return false;
- }
- if (!$srcImgInfo) {
- $srcImgInfo = getimagesize($src);
- }
- $watermark = $opts['source'];
- $quality = $opts['quality'];
- $transparency = $opts['transparency'];
- // check target image size
- if ($opts['targetMinPixel'] > 0 && $opts['targetMinPixel'] > min($srcImgInfo[0], $srcImgInfo[1])) {
- return false;
- }
- $watermark_width = $watermarkImgInfo[0];
- $watermark_height = $watermarkImgInfo[1];
- // Specified as a ratio to the image size
- if ($opts['ratio'] && $opts['ratio'] > 0 && $opts['ratio'] <= 1) {
- $maxW = $srcImgInfo[0] * $opts['ratio'] - ($opts['marginX'] * 2);
- $maxH = $srcImgInfo[1] * $opts['ratio'] - ($opts['marginY'] * 2);
- $dx = $dy = 0;
- if (($maxW >= $watermarkImgInfo[0] && $maxH >= $watermarkImgInfo[0]) || ($maxW <= $watermarkImgInfo[0] && $maxH <= $watermarkImgInfo[0])) {
- $dx = abs($srcImgInfo[0] - $watermarkImgInfo[0]);
- $dy = abs($srcImgInfo[1] - $watermarkImgInfo[1]);
- } else if ($maxW < $watermarkImgInfo[0]) {
- $dx = -1;
- } else {
- $dy = -1;
- }
- if ($dx < $dy) {
- $ww = $maxW;
- $wh = $watermarkImgInfo[1] * ($ww / $watermarkImgInfo[0]);
- } else {
- $wh = $maxH;
- $ww = $watermarkImgInfo[0] * ($wh / $watermarkImgInfo[1]);
- }
- $watermarkImgInfo[0] = $ww;
- $watermarkImgInfo[1] = $wh;
- } else {
- $opts['ratio'] = null;
- }
- $opts['position'] = strtoupper($opts['position']);
- // Set vertical position
- if (strpos($opts['position'], 'T') !== false) {
- // Top
- $dest_x = $opts['marginX'];
- } else if (strpos($opts['position'], 'M') !== false) {
- // Middle
- $dest_x = ($srcImgInfo[0] - $watermarkImgInfo[0]) / 2;
- } else {
- // Bottom
- $dest_x = $srcImgInfo[0] - $watermarkImgInfo[0] - max($opts['marginBottom'], $opts['marginX']);
- }
- // Set horizontal position
- if (strpos($opts['position'], 'L') !== false) {
- // Left
- $dest_y = $opts['marginY'];
- } else if (strpos($opts['position'], 'C') !== false) {
- // Middle
- $dest_y = ($srcImgInfo[1] - $watermarkImgInfo[1]) / 2;
- } else {
- // Right
- $dest_y = $srcImgInfo[1] - $watermarkImgInfo[1] - max($opts['marginRight'], $opts['marginY']);
- }
- // check interlace
- $opts['interlace'] = ($opts['interlace'] & $imgTypes[$imageType]);
- // Repeated use of Imagick::compositeImage() may cause PHP to hang, so disable it
- //if (class_exists('Imagick', false)) {
- // return $this->watermarkPrint_imagick($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $opts);
- //} else {
- elFinder::expandMemoryForGD(array($watermarkImgInfo, $srcImgInfo));
- return $this->watermarkPrint_gd($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $srcImgInfo, $opts);
- //}
- }
- private function watermarkPrint_imagick($src, $watermarkSrc, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $opts)
- {
- try {
- // Open the original image
- $img = new Imagick($src);
- // Open the watermark
- $watermark = new Imagick($watermarkSrc);
- // zoom
- if ($opts['ratio']) {
- $watermark->scaleImage($watermarkImgInfo[0], $watermarkImgInfo[1]);
- }
- // Set transparency
- if (strtoupper($watermark->getImageFormat()) !== 'PNG') {
- $watermark->setImageOpacity($transparency / 100);
- }
- // Overlay the watermark on the original image
- $img->compositeImage($watermark, imagick::COMPOSITE_OVER, $dest_x, $dest_y);
- // Set quality
- if (strtoupper($img->getImageFormat()) === 'JPEG') {
- $img->setImageCompression(imagick::COMPRESSION_JPEG);
- $img->setCompressionQuality($quality);
- }
- // set interlace
- $opts['interlace'] && $img->setInterlaceScheme(Imagick::INTERLACE_PLANE);
- $result = $img->writeImage($src);
- $img->clear();
- $img->destroy();
- $watermark->clear();
- $watermark->destroy();
- return $result ? true : false;
- } catch (Exception $e) {
- $ermsg = $e->getMessage();
- $ermsg && trigger_error($ermsg);
- return false;
- }
- }
- private function watermarkPrint_gd($src, $watermark, $dest_x, $dest_y, $quality, $transparency, $watermarkImgInfo, $srcImgInfo, $opts)
- {
- $watermark_width = $watermarkImgInfo[0];
- $watermark_height = $watermarkImgInfo[1];
- $ermsg = '';
- switch ($watermarkImgInfo['mime']) {
- case 'image/gif':
- if (imagetypes() & IMG_GIF) {
- $oWatermarkImg = imagecreatefromgif($watermark);
- } else {
- $ermsg = 'GIF images are not supported as watermark image';
- }
- break;
- case 'image/jpeg':
- if (imagetypes() & IMG_JPG) {
- $oWatermarkImg = imagecreatefromjpeg($watermark);
- } else {
- $ermsg = 'JPEG images are not supported as watermark image';
- }
- break;
- case 'image/png':
- if (imagetypes() & IMG_PNG) {
- $oWatermarkImg = imagecreatefrompng($watermark);
- } else {
- $ermsg = 'PNG images are not supported as watermark image';
- }
- break;
- case 'image/wbmp':
- if (imagetypes() & IMG_WBMP) {
- $oWatermarkImg = imagecreatefromwbmp($watermark);
- } else {
- $ermsg = 'WBMP images are not supported as watermark image';
- }
- break;
- default:
- $oWatermarkImg = false;
- $ermsg = $watermarkImgInfo['mime'] . ' images are not supported as watermark image';
- break;
- }
- if (!$ermsg) {
- // zoom
- if ($opts['ratio']) {
- $tmpImg = imagecreatetruecolor($watermarkImgInfo[0], $watermarkImgInfo[1]);
- imagealphablending($tmpImg, false);
- imagesavealpha($tmpImg, true);
- imagecopyresampled($tmpImg, $oWatermarkImg, 0, 0, 0, 0, $watermarkImgInfo[0], $watermarkImgInfo[1], imagesx($oWatermarkImg), imagesy($oWatermarkImg));
- imageDestroy($oWatermarkImg);
- $oWatermarkImg = $tmpImg;
- $tmpImg = null;
- }
- switch ($srcImgInfo['mime']) {
- case 'image/gif':
- if (imagetypes() & IMG_GIF) {
- $oSrcImg = imagecreatefromgif($src);
- } else {
- $ermsg = 'GIF images are not supported as source image';
- }
- break;
- case 'image/jpeg':
- if (imagetypes() & IMG_JPG) {
- $oSrcImg = imagecreatefromjpeg($src);
- } else {
- $ermsg = 'JPEG images are not supported as source image';
- }
- break;
- case 'image/png':
- if (imagetypes() & IMG_PNG) {
- $oSrcImg = imagecreatefrompng($src);
- } else {
- $ermsg = 'PNG images are not supported as source image';
- }
- break;
- case 'image/wbmp':
- if (imagetypes() & IMG_WBMP) {
- $oSrcImg = imagecreatefromwbmp($src);
- } else {
- $ermsg = 'WBMP images are not supported as source image';
- }
- break;
- default:
- $oSrcImg = false;
- $ermsg = $srcImgInfo['mime'] . ' images are not supported as source image';
- break;
- }
- }
- if ($ermsg || false === $oSrcImg || false === $oWatermarkImg) {
- $ermsg && trigger_error($ermsg);
- return false;
- }
- if ($srcImgInfo['mime'] === 'image/png') {
- if (function_exists('imagecolorallocatealpha')) {
- $bg = imagecolorallocatealpha($oSrcImg, 255, 255, 255, 127);
- imagefill($oSrcImg, 0, 0, $bg);
- }
- }
- if ($watermarkImgInfo['mime'] === 'image/png') {
- imagecopy($oSrcImg, $oWatermarkImg, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height);
- } else {
- imagecopymerge($oSrcImg, $oWatermarkImg, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, $transparency);
- }
- // set interlace
- $opts['interlace'] && imageinterlace($oSrcImg, true);
- switch ($srcImgInfo['mime']) {
- case 'image/gif':
- imagegif($oSrcImg, $src);
- break;
- case 'image/jpeg':
- imagejpeg($oSrcImg, $src, $quality);
- break;
- case 'image/png':
- if (function_exists('imagesavealpha') && function_exists('imagealphablending')) {
- imagealphablending($oSrcImg, false);
- imagesavealpha($oSrcImg, true);
- }
- imagepng($oSrcImg, $src);
- break;
- case 'image/wbmp':
- imagewbmp($oSrcImg, $src);
- break;
- }
- imageDestroy($oSrcImg);
- imageDestroy($oWatermarkImg);
- return true;
- }
- }
|