mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-17 15:03:25 +00:00
Update stamp and watermark to version 3.8
This commit is contained in:
@@ -11,6 +11,11 @@
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Symfony\Component\Process\ProcessBuilder;
|
||||
use MediaVorus\Media\Media;
|
||||
use Imagine\Image\ImagineInterface;
|
||||
use Imagine\Image\Color;
|
||||
use Imagine\Image\Box;
|
||||
use Imagine\Image\Point;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -30,39 +35,61 @@ class recordutils_image extends recordutils
|
||||
* @param int $width
|
||||
* @return Array
|
||||
*/
|
||||
protected function wrap($fontSize, $angle, $fontFace, $string, $width)
|
||||
protected function wrap(ImagineInterface $imagine, $fontSize, $angle, $fontFace, $string, $width)
|
||||
{
|
||||
$ret = array();
|
||||
|
||||
// str 'Op' used to calculate linespace
|
||||
$testbox = imagettfbbox($fontSize, $angle, $fontFace, 'Op');
|
||||
$height = abs($testbox[1] - ($dy = $testbox[7]));
|
||||
$font = $imagine->font($fontFace, $fontSize, new Color("000000", 0));
|
||||
$testbox = $font->box("0p", $angle);
|
||||
$height = $testbox->getHeight();
|
||||
$testbox = $font->box("M", $angle); // 1 em
|
||||
$dy = $testbox->getHeight();
|
||||
$toth = 0;
|
||||
$ret = array();
|
||||
|
||||
foreach (explode("\n", $string) as $lig) {
|
||||
if ($lig == '') {
|
||||
$ret[] = '';
|
||||
$ret[] = array('w' => 0, 'h' => $dy, 't' => '');
|
||||
$toth += $dy;
|
||||
} else {
|
||||
$buff = '';
|
||||
foreach (explode(' ', $lig) as $wrd) {
|
||||
$test = $buff . ($buff ? ' ' : '') . $wrd;
|
||||
$testbox = imagettfbbox($fontSize, $angle, $fontFace, $test);
|
||||
if (abs($testbox[2] - $testbox[0]) > $width) {
|
||||
if ($buff == '') {
|
||||
$ret[] = $test;
|
||||
$twords = array();
|
||||
$iword = -1;
|
||||
$lastc = '';
|
||||
for ($i = 0; $i < strlen($lig); $i++) {
|
||||
$c = $lig[$i];
|
||||
if ($iword == -1 || (ctype_space($c) && !ctype_space($lastc))) {
|
||||
$twords[++$iword] = array(($part = 0) => '', 1 => '');
|
||||
}
|
||||
if (!ctype_space($c) && $part == 0) {
|
||||
$part++;
|
||||
}
|
||||
$twords[$iword][$part] .= $lastc = $c;
|
||||
}
|
||||
if ($iword >= 0 && $twords[0][1] != '') {
|
||||
$buff = '';
|
||||
$lastw = $lasth = 0;
|
||||
foreach ($twords as $i => $wrd) {
|
||||
$test = $buff . $wrd[0] . $wrd[1];
|
||||
$testbox = $font->box($test, $angle);
|
||||
$w = $testbox->getWidth();
|
||||
$h = $testbox->getHeight();
|
||||
if ($i > 0 && $testbox->getWidth() > $width) {
|
||||
$ret[] = array('w' => $lastw, 'h' => $lasth, 't' => $buff);
|
||||
$toth += $lasth;
|
||||
$buff = $wrd[1];
|
||||
} else {
|
||||
$ret[] = $buff;
|
||||
$buff = $wrd;
|
||||
$buff = $test;
|
||||
}
|
||||
} else {
|
||||
$buff = $test;
|
||||
$lastw = $w;
|
||||
$lasth = $h;
|
||||
}
|
||||
if ($buff != '') {
|
||||
$ret[] = array('w' => $lastw, 'h' => $lasth, 't' => $buff);
|
||||
$toth += $lasth;
|
||||
}
|
||||
}
|
||||
if ($buff != '')
|
||||
$ret[] = $buff;
|
||||
}
|
||||
}
|
||||
|
||||
return(array('l' => $ret, 'h' => $height, 'dy' => $dy));
|
||||
return(array('toth' => $toth, 'l' => $ret, 'h' => $height, 'dy' => $dy));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,6 +101,25 @@ class recordutils_image extends recordutils
|
||||
*/
|
||||
public static function stamp(Application $app, \media_subdef $subdef)
|
||||
{
|
||||
$xmlToColor = function($attr, $ret = array(255, 255, 255, 0)) {
|
||||
foreach (explode(',', $attr) as $i => $v) {
|
||||
if ($i > 3)
|
||||
break;
|
||||
$v = (int) (trim($v));
|
||||
if ($v >= 0 && ($v <= 100 || ($i < 3 && $v < 256))) {
|
||||
$ret[$i] = $v;
|
||||
}
|
||||
}
|
||||
$alpha = array_pop($ret);
|
||||
return new Color($ret, $alpha);
|
||||
};
|
||||
|
||||
$Core = \bootstrap::getCore();
|
||||
|
||||
$imagine = $Core['imagine'];
|
||||
|
||||
$appbox = appbox::get_instance(\bootstrap::getCore());
|
||||
$registry = $appbox->get_registry();
|
||||
$base_id = $subdef->get_record()->get_base_id();
|
||||
$binaries = $app['phraseanet.configuration']['binaries'];
|
||||
|
||||
@@ -81,7 +127,7 @@ class recordutils_image extends recordutils
|
||||
return $subdef->get_pathfile();
|
||||
}
|
||||
|
||||
if ( ! $subdef->is_physically_present()) {
|
||||
if (!$subdef->is_physically_present()) {
|
||||
return $subdef->get_pathfile();
|
||||
}
|
||||
|
||||
@@ -89,216 +135,303 @@ class recordutils_image extends recordutils
|
||||
return $subdef->get_pathfile();
|
||||
}
|
||||
|
||||
$rotation = null;
|
||||
try {
|
||||
$image = $Core['mediavorus']->guess(new SplFileInfo($subdef->get_pathfile()));
|
||||
if (Media::TYPE_IMAGE === $image->getType()) {
|
||||
// One of MediaVorus\Media\Image::ORIENTATION_* constants
|
||||
$rotation = $image->getOrientation();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// getting orientation failed but we don't care the reason
|
||||
}
|
||||
|
||||
$domprefs = new DOMDocument();
|
||||
|
||||
if (false === $domprefs->loadXML($subdef->get_record()->get_collection()->get_prefs())) {
|
||||
if (false === $domprefs->loadXML(
|
||||
$subdef->get_record()->get_collection()->get_prefs())) {
|
||||
return $subdef->get_pathfile();
|
||||
}
|
||||
|
||||
if (false === $sxxml = simplexml_load_string($subdef->get_record()->get_caption()->serialize(caption_record::SERIALIZE_XML))) {
|
||||
if (false === $sxxml = simplexml_load_string(
|
||||
$subdef->get_record()->get_caption()->serialize(caption_record::SERIALIZE_XML))) {
|
||||
return $subdef->get_pathfile();
|
||||
}
|
||||
|
||||
$xpprefs = new DOMXPath($domprefs);
|
||||
|
||||
$pathIn = $subdef->get_path() . $subdef->get_file();
|
||||
$pathOut = $subdef->get_path() . 'stamp_' . $subdef->get_file();
|
||||
$pathTmpStamp = $app['root.path'] . '/tmp/' . time() . '-stamptmp_' . $subdef->get_file();
|
||||
|
||||
if ($xpprefs->query('/baseprefs/stamp')->length == 0) {
|
||||
$stampNodes = $xpprefs->query('/baseprefs/stamp');
|
||||
if ($stampNodes->length == 0) {
|
||||
return $subdef->get_pathfile();
|
||||
}
|
||||
|
||||
|
||||
$pathIn = $subdef->get_path() . $subdef->get_file();
|
||||
$pathOut = $subdef->get_path() . 'stamp_' . $subdef->get_file();
|
||||
|
||||
$vars = $xpprefs->query('/baseprefs/stamp/*/var');
|
||||
for ($i = 0; $i < $vars->length; $i ++) {
|
||||
$varval = '';
|
||||
$n = $vars->item($i);
|
||||
switch (strtoupper($n->getAttribute('name'))) {
|
||||
case 'DATE':
|
||||
if ( ! ($format = $n->getAttribute('format')))
|
||||
$format = 'Y/m/d H:i:s';
|
||||
$varval = date($format);
|
||||
@unlink($pathOut);
|
||||
break;
|
||||
case 'RECORD_ID':
|
||||
$varval = $subdef->get_record()->get_record_id();
|
||||
break;
|
||||
|
||||
// no way to cache when date changes
|
||||
for ($i = 0; $i < $vars->length; $i++) {
|
||||
if (strtoupper($vars->item($i)->getAttribute('name')) == 'DATE') {
|
||||
@unlink($pathOut);
|
||||
break;
|
||||
}
|
||||
$n->parentNode->replaceChild($domprefs->createTextNode($varval), $n);
|
||||
}
|
||||
|
||||
// get from cache ?
|
||||
if (is_file($pathOut)) {
|
||||
return $pathOut;
|
||||
}
|
||||
|
||||
$fields = $xpprefs->query('/baseprefs/stamp/*/field');
|
||||
for ($i = 0; $i < $fields->length; $i ++) {
|
||||
$fldval = '';
|
||||
$n = $fields->item($i);
|
||||
$fieldname = $n->getAttribute('name');
|
||||
|
||||
$x = $sxxml->description->{$fieldname};
|
||||
if (is_array($x)) {
|
||||
foreach ($x as $v)
|
||||
$fldval .= ( $fldval ? '; ' : '') . (string) $v;
|
||||
} else {
|
||||
$fldval .= ( $fldval ? '; ' : '') . (string) $x;
|
||||
}
|
||||
$n->parentNode->replaceChild($domprefs->createTextNode($fldval), $n);
|
||||
// open the document
|
||||
$image_in = $imagine->open($pathIn);
|
||||
$image_size = $image_in->getSize();
|
||||
switch ($rotation) {
|
||||
case MediaVorus\Media\Image::ORIENTATION_90:
|
||||
$image_width = $image_size->getHeight();
|
||||
$image_height = $image_size->getWidth();
|
||||
$image_in->rotate(90);
|
||||
$rotation = '90';
|
||||
break;
|
||||
case MediaVorus\Media\Image::ORIENTATION_270:
|
||||
$image_width = $image_size->getHeight();
|
||||
$image_height = $image_size->getWidth();
|
||||
$image_in->rotate(270);
|
||||
break;
|
||||
case MediaVorus\Media\Image::ORIENTATION_180:
|
||||
$image_width = $image_size->getWidth();
|
||||
$image_height = $image_size->getHeight();
|
||||
$image_in->rotate(180);
|
||||
break;
|
||||
default:
|
||||
$image_width = $image_size->getWidth();
|
||||
$image_height = $image_size->getHeight();
|
||||
break;
|
||||
}
|
||||
|
||||
$domprefs->normalizeDocument();
|
||||
|
||||
if ( ! ($tailleimg = @getimagesize($pathIn))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$image_width = $tailleimg[0];
|
||||
$image_height = $tailleimg[1];
|
||||
|
||||
$text_xpos = 0;
|
||||
$text_width = $image_width;
|
||||
|
||||
$logofile = $app['root.path'] . '/config/stamp/' . $base_id;
|
||||
$logopos = null;
|
||||
$imlogo = null; // gd image
|
||||
// open the logo
|
||||
$logo_phywidth = $logo_phyheight = 0; // physical size
|
||||
$logo_reswidth = $logo_resheight = 0; // resized size
|
||||
$logo_file = $registry->get('GV_RootPath') . 'config/stamp/' . $base_id;
|
||||
if (($logo_obj = $imagine->open($logo_file))) {
|
||||
$logo_size = $logo_obj->getSize();
|
||||
$logo_phywidth = $logo_size->getWidth();
|
||||
$logo_phyheight = $logo_size->getHeight();
|
||||
}
|
||||
|
||||
if (is_array($logosize = @getimagesize($logofile))) {
|
||||
$logo_reswidth = $logo_phywidth = $logosize[0];
|
||||
$logo_resheight = $logo_phyheight = $logosize[1];
|
||||
$tables = array(
|
||||
'TOP' => array('h' => 0, 'rows' => array()),
|
||||
'TOP-OVER' => array('h' => 0, 'rows' => array()),
|
||||
'BOTTOM' => array('h' => 0, 'rows' => array()),
|
||||
'BOTTOM-OVER' => array('h' => 0, 'rows' => array())
|
||||
);
|
||||
|
||||
$v = $xpprefs->query('/baseprefs/stamp/logo');
|
||||
if ($v->length > 0) {
|
||||
$logopos = @strtoupper($v->item(0)->getAttribute('position'));
|
||||
if (($logowidth = trim($v->item(0)->getAttribute('width'))) != '') {
|
||||
if (substr($logowidth, -1) == '%')
|
||||
$logo_reswidth = (int) ($logowidth * $image_width / 100);
|
||||
else
|
||||
$logo_reswidth = (int) $logowidth;
|
||||
$logo_resheight = (int) ($logo_phyheight *
|
||||
($logo_reswidth / $logo_phywidth));
|
||||
for ($istamp = 0; $istamp < $stampNodes->length; $istamp++) {
|
||||
$stamp = $stampNodes->item($istamp);
|
||||
|
||||
$stamp_background = $xmlToColor($stamp->getAttribute('background'), array(255, 255, 255, 0));
|
||||
|
||||
$stamp_position = strtoupper(trim($stamp->getAttribute('position')));
|
||||
if (!in_array($stamp_position, array('TOP', 'TOP-OVER', 'BOTTOM-OVER', 'BOTTOM'))) {
|
||||
$stamp_position = 'BOTTOM';
|
||||
}
|
||||
|
||||
// replace "var" nodes with their value
|
||||
$vars = $xpprefs->query('*/var', $stamp);
|
||||
for ($i = 0; $i < $vars->length; $i++) {
|
||||
$varval = '';
|
||||
$n = $vars->item($i);
|
||||
switch (strtoupper($n->getAttribute('name'))) {
|
||||
case 'DATE':
|
||||
if (!($format = $n->getAttribute('format')))
|
||||
$format = 'Y/m/d H:i:s';
|
||||
$varval = date($format);
|
||||
@unlink($pathOut); // no cache possible when date changes
|
||||
break;
|
||||
case 'RECORD_ID':
|
||||
$varval = $rec;
|
||||
break;
|
||||
}
|
||||
$n->parentNode->replaceChild($domprefs->createTextNode($varval), $n);
|
||||
}
|
||||
|
||||
if (($logopos == 'LEFT' || $logopos == 'RIGHT') &&
|
||||
$logo_phywidth > 0 && $logo_phyheight > 0) {
|
||||
switch ($logosize['mime']) {
|
||||
case 'image/gif':
|
||||
$imlogo = @imagecreatefromgif($logofile);
|
||||
break;
|
||||
case 'image/png':
|
||||
$imlogo = @imagecreatefrompng($logofile);
|
||||
break;
|
||||
case 'image/jpeg':
|
||||
case 'image/pjpeg':
|
||||
$imlogo = @imagecreatefromjpeg($logofile);
|
||||
break;
|
||||
// replace "field" nodes with their values
|
||||
$fields = $xpprefs->query('*/field', $stamp);
|
||||
for ($i = 0; $i < $fields->length; $i++) {
|
||||
$fldval = '';
|
||||
$n = $fields->item($i);
|
||||
$fieldname = $n->getAttribute('name');
|
||||
|
||||
$x = $sxxml->description->{$fieldname};
|
||||
if (is_array($x)) {
|
||||
foreach ($x as $v)
|
||||
$fldval .= ( $fldval ? '; ' : '') . (string) $v;
|
||||
} else {
|
||||
$fldval .= ( $fldval ? '; ' : '') . (string) $x;
|
||||
}
|
||||
$n->parentNode->replaceChild($domprefs->createTextNode($fldval), $n);
|
||||
}
|
||||
|
||||
$domprefs->normalizeDocument();
|
||||
|
||||
$text_xpos = 0;
|
||||
$text_width = $image_width;
|
||||
|
||||
$logopos = null;
|
||||
|
||||
// compute logo position / size
|
||||
$logo_reswidth = 0;
|
||||
$logo_resheight = 0;
|
||||
if ($logo_phywidth > 0 && $logo_phyheight > 0) {
|
||||
|
||||
$v = $xpprefs->query('logo', $stamp);
|
||||
if ($v->length > 0) {
|
||||
$logo_reswidth = $logo_phywidth;
|
||||
$logo_resheight = $logo_phyheight;
|
||||
$logopos = @strtoupper($v->item(0)->getAttribute('position'));
|
||||
if (($logowidth = trim($v->item(0)->getAttribute('width'))) != '') {
|
||||
if (substr($logowidth, -1) == '%')
|
||||
$logo_reswidth = (int) ($logowidth * $image_width / 100);
|
||||
else
|
||||
$logo_reswidth = (int) $logowidth;
|
||||
$logo_resheight = (int) ($logo_phyheight *
|
||||
($logo_reswidth / $logo_phywidth));
|
||||
}
|
||||
if ($imlogo) {
|
||||
|
||||
if ($logopos == 'LEFT' || $logopos == 'RIGHT') {
|
||||
|
||||
if ($logo_reswidth > $image_width / 2) {
|
||||
// logo too large, resize please
|
||||
$logo_reswidth = (int) ($image_width / 2);
|
||||
$logo_resheight = (int) ($logo_phyheight *
|
||||
($logo_reswidth / $logo_phywidth));
|
||||
}
|
||||
|
||||
$text_width -= ( $text_xpos = $logo_reswidth);
|
||||
$text_width -= $logo_reswidth;
|
||||
if ($logopos == 'LEFT') {
|
||||
$logo_xpos = 0;
|
||||
$text_xpos = $logo_reswidth;
|
||||
} else { // RIGHT
|
||||
$text_xpos = 0;
|
||||
$logo_xpos = ($image_width - $logo_reswidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$txth = 0;
|
||||
$txtblock = array();
|
||||
$texts = $xpprefs->query('/baseprefs/stamp/text');
|
||||
$fontsize = "100%";
|
||||
for ($i = 0; $i < $texts->length; $i ++) {
|
||||
if (($tmpfontsize = trim($texts->item($i)->getAttribute('size'))) != '') {
|
||||
if (substr($tmpfontsize, -1) == '%')
|
||||
$tmpfontsize = (int) ($tmpfontsize * $image_width / 4000);
|
||||
else
|
||||
$tmpfontsize = (int) $tmpfontsize;
|
||||
$fontsize = $tmpfontsize;
|
||||
|
||||
// compute text blocks
|
||||
$txth = 0;
|
||||
$txtblock = array();
|
||||
$texts = $xpprefs->query('text', $stamp);
|
||||
$fontsize = "100%";
|
||||
for ($i = 0; $i < $texts->length; $i++) {
|
||||
if (($tmpfontsize = trim($texts->item($i)->getAttribute('size'))) != '') {
|
||||
if (substr($tmpfontsize, -1) == '%')
|
||||
$tmpfontsize = (int) ($tmpfontsize * $image_width / 4000);
|
||||
else
|
||||
$tmpfontsize = (int) $tmpfontsize;
|
||||
$fontsize = $tmpfontsize;
|
||||
}
|
||||
|
||||
if ($fontsize < 2)
|
||||
$fontsize = 2;
|
||||
elseif ($fontsize > 300)
|
||||
$fontsize = 300;
|
||||
|
||||
$txtline = $texts->item($i)->nodeValue;
|
||||
|
||||
if ($txtline != '') {
|
||||
$wrap = recordutils_image::wrap($imagine, $fontsize, 0, __DIR__ . '/arial.ttf', $txtline, $text_width
|
||||
);
|
||||
$txtblock[] = array(
|
||||
'fontsize' => $fontsize,
|
||||
'fontcolor' => $xmlToColor($texts->item($i)->getAttribute('color'), array(0, 0, 0, 0)),
|
||||
'h' => $wrap['toth'],
|
||||
'lines' => $wrap['l']
|
||||
);
|
||||
$txth += $wrap['toth'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($fontsize < 2)
|
||||
$fontsize = 2;
|
||||
elseif ($fontsize > 300)
|
||||
$fontsize = 300;
|
||||
$stampheight = max($logo_resheight, $txth);
|
||||
|
||||
$txtline = $texts->item($i)->nodeValue;
|
||||
if ($stamp_position == 'TOP-OVER' || $stamp_position == 'BOTTOM-OVER') {
|
||||
if ($tables[$stamp_position]['h'] + $stampheight > $image_height) {
|
||||
$stampheight = $image_height - $tables[$stamp_position]['h'];
|
||||
}
|
||||
}
|
||||
if ($stampheight <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($txtline != '') {
|
||||
$txtlines = recordutils_image::wrap(
|
||||
$fontsize, 0, __DIR__ . '/arial.ttf', $txtline, $text_width
|
||||
);
|
||||
// create the block
|
||||
$imfg = $imagine->create(new Box($image_width, $stampheight), $stamp_background);
|
||||
|
||||
foreach ($txtlines['l'] as $txtline) {
|
||||
$txtblock[] = array(
|
||||
'x' => $text_xpos,
|
||||
'dy' => $txtlines['dy'],
|
||||
'w' => $text_width,
|
||||
'h' => $txtlines['h'],
|
||||
't' => $txtline,
|
||||
's' => $fontsize
|
||||
);
|
||||
$txth += $txtlines['h'];
|
||||
// copy the logo
|
||||
if ($logo_reswidth > 0 && $logo_resheight > 0) {
|
||||
if ($logo_reswidth != $logo_phywidth) {
|
||||
$imfg->paste(
|
||||
$logo_obj->copy()->resize(new Box($logo_reswidth, $logo_resheight))
|
||||
, new Point($logo_xpos, 0));
|
||||
} else {
|
||||
$imfg->paste($logo_obj, new Point($logo_xpos, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// fill with text
|
||||
$draw = $imfg->draw();
|
||||
$txt_ypos = 0;
|
||||
foreach ($txtblock as $block) {
|
||||
$font = $imagine->font(__DIR__ . '/arial.ttf', $block['fontsize'], $block['fontcolor']);
|
||||
foreach ($block['lines'] as $line) {
|
||||
if ($line['t'] != '') {
|
||||
$draw->text($line['t'], $font, new Point(0, $txt_ypos), 0);
|
||||
}
|
||||
$txt_ypos += $line['h'];
|
||||
}
|
||||
}
|
||||
|
||||
// memo into one of the 4 buffer
|
||||
$tables[$stamp_position]['rows'][] = array(
|
||||
'x0' => 0,
|
||||
'y0' => $tables[$stamp_position]['h'],
|
||||
'w' => $image_width,
|
||||
'h' => $stampheight,
|
||||
'img' => $imfg
|
||||
);
|
||||
|
||||
$tables[$stamp_position]['h'] += $stampheight;
|
||||
}
|
||||
|
||||
$newh = $tables['TOP']['h'] + $image_height + $tables['BOTTOM']['h'];
|
||||
|
||||
// create the output image
|
||||
$image_out = $imagine->create(new Box($image_width, $newh), new Color("FFFFFF", 64));
|
||||
|
||||
// paste the input image into
|
||||
$image_out->paste($image_in, new Point(0, $tables['TOP']['h']));
|
||||
|
||||
|
||||
// fix the coordinates
|
||||
foreach ($tables['TOP-OVER']['rows'] as $k => $row) {
|
||||
$tables['TOP-OVER']['rows'][$k]['y0'] += $tables['TOP']['h'];
|
||||
}
|
||||
foreach ($tables['BOTTOM-OVER']['rows'] as $k => $row) {
|
||||
$tables['BOTTOM-OVER']['rows'][$k]['y0'] += $tables['TOP']['h'] + $image_height - $tables['BOTTOM-OVER']['h'];
|
||||
}
|
||||
foreach ($tables['BOTTOM']['rows'] as $k => $row) {
|
||||
$tables['BOTTOM']['rows'][$k]['y0'] += $tables['TOP']['h'] + $image_height;
|
||||
}
|
||||
|
||||
// paste blocks
|
||||
foreach (array('TOP', 'TOP-OVER', 'BOTTOM-OVER', 'BOTTOM') as $ta) {
|
||||
foreach ($tables[$ta]['rows'] as $row) {
|
||||
if ($row['h'] > 0) {
|
||||
$image_out->paste($row['img'], new Point($row['x0'], $row['y0']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$stampheight = max($logo_resheight, $txth);
|
||||
|
||||
$im = imagecreatetruecolor($image_width, $stampheight);
|
||||
|
||||
$white = imagecolorallocate($im, 255, 255, 255);
|
||||
imagefilledrectangle($im, 0, 0, $image_width, $stampheight, $white);
|
||||
imagecolordeallocate($im, $white);
|
||||
|
||||
if ($imlogo) {
|
||||
if ($logo_reswidth != $logo_phywidth) {
|
||||
imagecopyresampled($im, $imlogo, 0, 0, // dst_x, dst_y
|
||||
0, 0, // src_x, src_y
|
||||
$logo_reswidth, // dst_w
|
||||
$logo_resheight, // dst_h
|
||||
$logo_phywidth, // src_w
|
||||
$logo_phyheight // src_h
|
||||
);
|
||||
} else {
|
||||
imagecopy($im, $imlogo, 0, 0, // dst_x, dst_y
|
||||
0, 0, // src_x, src_y
|
||||
$logo_phywidth, // src_w
|
||||
$logo_phyheight // src_h
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($txtblock) >= 0) {
|
||||
$black = imagecolorallocate($im, 0, 0, 0);
|
||||
$txt_ypos = 0; //$txtblock[0]['h'];
|
||||
foreach ($txtblock as $block) {
|
||||
imagettftext($im, $block['s'], 0, $block['x'], $txt_ypos - $block['dy'], $black, __DIR__ . '/arial.ttf', $block['t']);
|
||||
$txt_ypos += $block['h'];
|
||||
}
|
||||
imagecolordeallocate($im, $black);
|
||||
}
|
||||
imagejpeg($im, $pathTmpStamp, 80);
|
||||
|
||||
imagedestroy($im);
|
||||
|
||||
$newh = $image_height + $stampheight;
|
||||
|
||||
$builder = ProcessBuilder::create(array($binaries['convert_binary']));
|
||||
$builder->add('-extent')
|
||||
->add($image_width . 'x' . $newh)
|
||||
->add('-draw')
|
||||
->add('image SrcOver 0,' . $image_height . ' ' . $image_width . ',' . $stampheight . '"' . $pathTmpStamp . '"')
|
||||
->add($pathIn)
|
||||
->add($pathOut);
|
||||
|
||||
$builder->getProcess()->run();
|
||||
|
||||
unlink($pathTmpStamp);
|
||||
// save the output
|
||||
$image_out->save($pathOut);
|
||||
|
||||
if (is_file($pathOut)) {
|
||||
return $pathOut;
|
||||
@@ -316,6 +449,12 @@ class recordutils_image extends recordutils
|
||||
*/
|
||||
public static function watermark(Application $app, \media_subdef $subdef)
|
||||
{
|
||||
$Core = \bootstrap::getCore();
|
||||
|
||||
$imagine = $Core['imagine'];
|
||||
$appbox = appbox::get_instance($Core);
|
||||
|
||||
$registry = $appbox->get_registry();
|
||||
$base_id = $subdef->get_record()->get_base_id();
|
||||
$binaries = $app['phraseanet.configuration']['binaries'];
|
||||
|
||||
@@ -327,68 +466,79 @@ class recordutils_image extends recordutils
|
||||
return $subdef->get_pathfile();
|
||||
}
|
||||
|
||||
if ( ! $subdef->is_physically_present()) {
|
||||
return $subdef->get_pathfile();
|
||||
if (!$subdef->is_physically_present()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pathIn = $subdef->get_path() . $subdef->get_file();
|
||||
|
||||
$pathOut = $subdef->get_path() . 'watermark_' . $subdef->get_file();
|
||||
|
||||
if (!is_file($pathIn)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pathOut = $subdef->get_path() . 'watermark_' . $subdef->get_file();
|
||||
|
||||
// cache
|
||||
if (is_file($pathOut)) {
|
||||
return $pathOut;
|
||||
}
|
||||
|
||||
if (isset($binaries['composite_binary']) &&
|
||||
file_exists($app['root.path'] . '/config/wm/' . $base_id)) {
|
||||
$in_image = $imagine->open($pathIn);
|
||||
$in_size = $in_image->getSize();
|
||||
$in_w = $in_size->getWidth();
|
||||
$in_h = $in_size->getHeight();
|
||||
|
||||
$builder = ProcessBuilder::create(array(
|
||||
$binaries['composite_binary'],
|
||||
$app['root.path'] . '/config/wm/' . $base_id,
|
||||
$pathIn,
|
||||
'-strip', '-watermark', '90%', '-gravity', 'center',
|
||||
$pathOut
|
||||
));
|
||||
$wm_file = $registry->get('GV_RootPath') . 'config/wm/' . $base_id;
|
||||
if (file_exists($wm_file)) {
|
||||
$wm_image = $imagine->open($wm_file);
|
||||
$wm_size = $wm_image->getSize();
|
||||
$wm_w = $wm_size->getWidth();
|
||||
$wm_h = $wm_size->getHeight();
|
||||
|
||||
$builder->getProcess()->run();
|
||||
} elseif (isset($binaries['convert_binary'])) {
|
||||
$collname = phrasea::bas_labels($base_id, $app);
|
||||
$tailleimg = @getimagesize($pathIn);
|
||||
$max = ($tailleimg[0] > $tailleimg[1] ? $tailleimg[0] : $tailleimg[1]);
|
||||
if (($wm_w / $wm_h) > ($in_w / $in_h)) {
|
||||
$wm_size = $wm_size->widen($in_w);
|
||||
} else {
|
||||
$wm_size = $wm_size->heighten($in_h);
|
||||
}
|
||||
$wm_image->resize($wm_size);
|
||||
|
||||
$tailleText = (int) ($max / 30);
|
||||
$in_image->paste($wm_image, new Point(($in_w - $wm_size->getWidth()) >> 1, ($in_h - $wm_size->getHeight()) >> 1))->save($pathOut);
|
||||
} else {
|
||||
$collname = phrasea::bas_names($base_id);
|
||||
$draw = $in_image->draw();
|
||||
$black = new Color("000000");
|
||||
$white = new Color("FFFFFF");
|
||||
$draw->line(new Point(0, 1), new Point($in_w - 2, $in_h - 1), $black);
|
||||
$draw->line(new Point(1, 0), new Point($in_w - 1, $in_h - 2), $white);
|
||||
$draw->line(new Point(0, $in_h - 2), new Point($in_w - 2, 0), $black);
|
||||
$draw->line(new Point(1, $in_h - 1), new Point($in_w - 1, 1), $white);
|
||||
|
||||
if ($tailleText < 8)
|
||||
$tailleText = 8;
|
||||
$fsize = max(8, (int) (max($in_w, $in_h) / 30));
|
||||
$fonts = array(
|
||||
$imagine->font(__DIR__ . '/arial.ttf', $fsize, $black),
|
||||
$imagine->font(__DIR__ . '/arial.ttf', $fsize, $white)
|
||||
);
|
||||
$testbox = $fonts[0]->box($collname, 0);
|
||||
$tx_w = min($in_w, $testbox->getWidth());
|
||||
$tx_h = min($in_h, $testbox->getHeight());
|
||||
|
||||
if ($tailleText > 12)
|
||||
$decalage = 2;
|
||||
else
|
||||
$decalage = 1;
|
||||
$x0 = max(1, ($in_w - $tx_w) >> 1);
|
||||
$y0 = max(1, ($in_h - $tx_h) >> 1);
|
||||
for ($i = 0; $i <= 1; $i++) {
|
||||
$x = max(1, ($in_w >> 2) - ($tx_w >> 1));
|
||||
$draw->text($collname, $fonts[$i], new Point($x - $i, $y0 - $i), 0);
|
||||
$x = max(1, $in_w - $x - $tx_w);
|
||||
$draw->text($collname, $fonts[$i], new Point($x - $i, $y0 - $i), 0);
|
||||
|
||||
$builder = ProcessBuilder::create(array(
|
||||
$binaries['convert_binary'],
|
||||
'-fill', 'white', '-draw', 'line 0,0 ' . $tailleimg[0] . ',' . $tailleimg[1] . '',
|
||||
'-fill', 'black', '-draw', 'line 1,0 ' . $tailleimg[0] + 1 . ',' . $tailleimg[1] . '',
|
||||
'-fill', 'white', '-draw', 'line ' . $tailleimg[0] . ',0 0,' . $tailleimg[1] . '',
|
||||
'-fill', 'black', '-draw', 'line ' . ($tailleimg[0] + 1) . ',0 0,' . $tailleimg[1] . '',
|
||||
'-fill', 'white', '-gravity', 'NorthWest', '-pointsize', $tailleText, '-draw', 'text 0,0 ' . $collname,
|
||||
'-fill', 'black', '-gravity', 'NorthWest', '-pointsize', $tailleText, '-draw', 'text ' . $decalage . ', 1 ' . $collname,
|
||||
'-fill', 'white', '-gravity', 'center', '-pointsize', $tailleText, '-draw', 'text 0,0 ' . $collname,
|
||||
'-fill', 'black', '-gravity', 'center', '-pointsize', $tailleText, '-draw', 'text ' . $decalage . ', 1 ' . $collname,
|
||||
'-fill', 'white', '-gravity', 'SouthEast', '-pointsize', $tailleText, '-draw', 'text 0,0 ' . $collname,
|
||||
'-fill', 'black', '-gravity', 'SouthEast', '-pointsize', $tailleText, '-draw', 'text ' . $decalage . ', 1 ' . $collname,
|
||||
$pathIn, $pathOut
|
||||
));
|
||||
|
||||
$process = $builder->getProcess();
|
||||
$process->run();
|
||||
$y = max(1, ($in_h >> 2) - ($tx_h >> 1));
|
||||
$draw->text($collname, $fonts[$i], new Point($x0 - $i, $y - $i), 0);
|
||||
$y = max(1, $in_h - $y - $tx_h);
|
||||
$draw->text($collname, $fonts[$i], new Point($x0 - $i, $y - $i), 0);
|
||||
}
|
||||
}
|
||||
|
||||
$in_image->save($pathOut);
|
||||
|
||||
if (is_file($pathOut)) {
|
||||
return $pathOut;
|
||||
}
|
||||
|
Reference in New Issue
Block a user