From 7bd79acad27cecaca4d73666107454a6e0db0de4 Mon Sep 17 00:00:00 2001 From: jygaulier Date: Thu, 28 Feb 2013 19:13:49 +0100 Subject: [PATCH 1/4] some fixes to stamper, add options for over-image stamp & alpha colors --- lib/classes/recordutils/image.class.php | 468 +++++++++++++++--------- 1 file changed, 296 insertions(+), 172 deletions(-) diff --git a/lib/classes/recordutils/image.class.php b/lib/classes/recordutils/image.class.php index 1d06358b7b..0d19200d2b 100644 --- a/lib/classes/recordutils/image.class.php +++ b/lib/classes/recordutils/image.class.php @@ -73,6 +73,18 @@ class recordutils_image extends recordutils */ public static function stamp(\media_subdef $subdef) { + $ColorToArray = 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 <= 127 || ($i < 3 && $v < 256))) { + $ret[$i] = $v; + } + } + return($ret); + }; + $appbox = appbox::get_instance(\bootstrap::getCore()); $registry = $appbox->get_registry(); $base_id = $subdef->get_record()->get_base_id(); @@ -81,11 +93,11 @@ class recordutils_image extends recordutils return $subdef->get_pathfile(); } - if ( ! $subdef->is_physically_present()) { + if (!$subdef->is_physically_present()) { return $subdef->get_pathfile(); } - if ( ! $registry->get('convert_binary')) { + if (!$registry->get('convert_binary')) { return $subdef->get_pathfile(); } @@ -103,202 +115,315 @@ class recordutils_image extends recordutils $pathIn = $subdef->get_path() . $subdef->get_file(); $pathOut = $subdef->get_path() . 'stamp_' . $subdef->get_file(); - $pathTmpStamp = $registry->get('GV_RootPath') . 'tmp/' . time() . '-stamptmp_' . $subdef->get_file(); - - if ($xpprefs->query('/baseprefs/stamp')->length == 0) { - return $subdef->get_pathfile(); - } $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 = $rec; - break; + for ($i = 0; $i < $vars->length; $i++) { + if (strtoupper($vars->item($i)->getAttribute('name')) == 'DATE') { + @unlink($pathOut); // no cache possible when date changes + 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'); + $logofile = $registry->get('GV_RootPath') . 'config/stamp/' . $base_id; + $logo_phywidth = $logo_phyheight = 0; // physical size - $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); + if (is_array($logosize = @getimagesize($logofile))) { + $logo_phywidth = $logosize[0]; + $logo_phyheight = $logosize[1]; } - $domprefs->normalizeDocument(); + $pathTmpStamp = $registry->get('GV_RootPath') . 'tmp/' . time() . '-stamptmp_' . $subdef->get_file(); + $stampNodes = $xpprefs->query('/baseprefs/stamp'); + if ($stampNodes->length == 0) { + return $subdef->get_pathfile(); + } - if ( ! ($tailleimg = @getimagesize($pathIn))) { + if (!($tailleimg = @getimagesize($pathIn))) { return false; } $image_width = $tailleimg[0]; $image_height = $tailleimg[1]; - $text_xpos = 0; - $text_width = $image_width; + $builder = ProcessBuilder::create(array($registry->get('convert_binary'))); - $logofile = $registry->get('GV_RootPath') . 'config/stamp/' . $base_id; - $logopos = null; - $imlogo = null; // gd image - $logo_phywidth = $logo_phyheight = 0; // physical size - $logo_reswidth = $logo_resheight = 0; // resized size + $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()) + ); - if (is_array($logosize = @getimagesize($logofile))) { - $logo_reswidth = $logo_phywidth = $logosize[0]; - $logo_resheight = $logo_phyheight = $logosize[1]; + for ($istamp = 0; $istamp < $stampNodes->length; $istamp++) { + $stamp = $stampNodes->item($istamp); - $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)); + $stamp_background = $ColorToArray($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'; + } + + $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; + $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; + $imlogo = null; // gd image + + $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 ($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)); + + 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; } - $text_width -= ( $text_xpos = $logo_reswidth); + if ($imlogo) { + 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 -= $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; + $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; + } + $txtColor = $ColorToArray($texts->item($i)->getAttribute('color'), array(0, 0, 0, 0)); + + if ($fontsize < 2) + $fontsize = 2; + elseif ($fontsize > 300) + $fontsize = 300; + + $txtline = $texts->item($i)->nodeValue; + + if ($txtline != '') { + $txtlines = recordutils_image::wrap( + $fontsize, 0, __DIR__ . '/arial.ttf', $txtline, $text_width + ); + + foreach ($txtlines['l'] as $txtline) { + $txtblock[] = array( + 'x' => $text_xpos, + 'dy' => $txtlines['dy'], + 'w' => $text_width, + 'h' => $txtlines['h'], + 't' => $txtline, + 's' => $fontsize, + 'k' => $txtColor + ); + $txth += $txtlines['h']; + } + } } - 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; + } + $imfg = imagecreatetruecolor($image_width, $stampheight); + imagesavealpha($imfg, true); + imagelayereffect($imfg, IMG_EFFECT_REPLACE); + $trans_colour = imagecolorallocatealpha($imfg, 0, 0, 0, 127); + imagefilledrectangle($imfg, 0, 0, $image_width, $stampheight, $trans_colour); + imagecolordeallocate($imfg, $trans_colour); - if ($txtline != '') { - $txtlines = recordutils_image::wrap( - $fontsize, 0, __DIR__ . '/arial.ttf', $txtline, $text_width - ); - - foreach ($txtlines['l'] as $txtline) { - $txtblock[] = array( - 'x' => $text_xpos, - 'dy' => $txtlines['dy'], - 'w' => $text_width, - 'h' => $txtlines['h'], - 't' => $txtline, - 's' => $fontsize + if ($imlogo) { + if ($logo_reswidth != $logo_phywidth) { + imagecopyresampled($imfg, $imlogo, $logo_xpos, 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 ); - $txth += $txtlines['h']; + } else { + imagecopy($imfg, $imlogo, $logo_xpos, 0, // dst_x, dst_y + 0, 0, // src_x, src_y + $logo_phywidth, // src_w + $logo_phyheight // src_h + ); + } + } + + if (count($txtblock) >= 0) { + $txt_ypos = 0; //$txtblock[0]['h']; + foreach ($txtblock as $block) { + $k = $block['k']; + $color = imagecolorallocatealpha($imfg, $k[0], $k[1], $k[2], $k[3]); + imagettftext($imfg, $block['s'], 0, $block['x'], $txt_ypos - $block['dy'], $color, __DIR__ . '/arial.ttf', $block['t']); + $txt_ypos += $block['h']; + imagecolordeallocate($imfg, $color); + } + } + + imagepng($imfg, $pathTmpStamp . '_' . $istamp . 'fg.png'); + imagedestroy($imfg); + + $bgfile = null; + if ($stamp_background[3] != 127) { // no need if background is transparent + $imbg = imagecreatetruecolor($image_width, $stampheight); + imagesavealpha($imbg, true); + imagelayereffect($imbg, IMG_EFFECT_REPLACE); + $trans_colour = imagecolorallocatealpha($imbg, $stamp_background[0], $stamp_background[1], $stamp_background[2], $stamp_background[3]); + imagefilledrectangle($imbg, 0, 0, $image_width, $stampheight, $trans_colour); + imagecolordeallocate($imbg, $trans_colour); + + imagepng($imbg, $pathTmpStamp . '_' . $istamp . 'bg.png'); + imagedestroy($imbg); + + $bgfile = $pathTmpStamp . '_' . $istamp . 'bg.png'; + } + + $tables[$stamp_position]['rows'][] = array( + 'x0' => 0, + 'y0' => $tables[$stamp_position]['h'], + 'w' => $image_width, + 'h' => $stampheight, + 'bgfile' => $bgfile, + 'fgfile' => $pathTmpStamp . '_' . $istamp . 'fg.png' + ); + + $tables[$stamp_position]['h'] += $stampheight; + } + + $newh = $tables['TOP']['h'] + $image_height + $tables['BOTTOM']['h']; + if ($newh != $image_height) { + $builder->add('-extent') + ->add($image_width . 'x' . $newh . '+0-' . $tables['TOP']['h']); + } + + 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; + } + + foreach (array('TOP', 'TOP-OVER', 'BOTTOM-OVER', 'BOTTOM') as $ta) { + foreach ($tables[$ta]['rows'] as $row) { + if ($row['h'] > 0) { + if ($row['bgfile']) { + $builder->add('-draw') + ->add('image Over ' . $row['x0'] . ',' . $row['y0'] . ' ' . $row['w'] . ',' . $row['h'] . ' "' . $row['bgfile'] . '"'); + } + $builder->add('-draw') + ->add('image Over ' . $row['x0'] . ',' . $row['y0'] . ' ' . $row['w'] . ',' . $row['h'] . ' "' . $row['fgfile'] . '"'); } } } - $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($registry->get('convert_binary'))); - $builder->add('-extent') - ->add($image_width . 'x' . $newh) - ->add('-draw') - ->add('image SrcOver 0,' . $image_height . ' ' . $image_width . ',' . $stampheight . '"' . $pathTmpStamp . '"') - ->add($pathIn) + $builder->add($pathIn) ->add($pathOut); - $builder->getProcess()->run(); + $process = $builder->getProcess(); - unlink($pathTmpStamp); + $process->run(); + + foreach (array('TOP', 'TOP-OVER', 'BOTTOM-OVER', 'BOTTOM') as $ta) { + foreach ($tables[$ta]['rows'] as $row) { + if ($row['bgfile']) { + @unlink($row['bgfile']); + } + @unlink($row['fgfile']); + } + } if (is_file($pathOut)) { return $pathOut; @@ -326,14 +451,14 @@ class recordutils_image extends recordutils return $subdef->get_pathfile(); } - if ( ! $subdef->is_physically_present()) { + if (!$subdef->is_physically_present()) { return $subdef->get_pathfile(); } $pathIn = $subdef->get_path() . $subdef->get_file(); $pathOut = $subdef->get_path() . 'watermark_' . $subdef->get_file(); - + if (!is_file($pathIn)) { return false; } @@ -370,24 +495,23 @@ class recordutils_image extends recordutils $decalage = 1; $builder = ProcessBuilder::create(array( - $registry->get('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 - )); + $registry->get('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(); } - if (is_file($pathOut)) { return $pathOut; } From da335ad65e9ca7a81c41b73925014f14a601445d Mon Sep 17 00:00:00 2001 From: jygaulier Date: Tue, 12 Mar 2013 15:39:51 +0100 Subject: [PATCH 2/4] watermark with imagine --- lib/Alchemy/Phrasea/Core.php | 19 + lib/classes/recordutils/image.class.php | 482 +++++++++++++----------- 2 files changed, 275 insertions(+), 226 deletions(-) diff --git a/lib/Alchemy/Phrasea/Core.php b/lib/Alchemy/Phrasea/Core.php index 5e3812bb31..c6a5ceddd8 100644 --- a/lib/Alchemy/Phrasea/Core.php +++ b/lib/Alchemy/Phrasea/Core.php @@ -12,6 +12,7 @@ namespace Alchemy\Phrasea; use Alchemy\Phrasea\Core\Configuration; +use Alchemy\Phrasea\Exception\RuntimeException; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Serializer; @@ -201,6 +202,24 @@ class Core extends \Pimple return new \MediaAlchemyst\Alchemyst($drivers); }); + $this['imagine'] = $this->share(function ($app) use ($core) { + + if ($core->getRegistry()->get('GV_imagine_driver')) { + $driver = $core->getRegistry()->get('GV_imagine_driver'); + } elseif (extension_loaded('gmagick')) { + $driver = 'Gmagick'; + } elseif (extension_loaded('imagick')) { + $driver = 'Imagick'; + } elseif (extension_loaded('gd')) { + $driver = 'Gd'; + } else { + throw new RuntimeException('Unable to find an Imagine driver'); + } + $classname = sprintf('\Imagine\%s\Imagine', $driver); + + return new $classname(); + }); + $this['border-manager'] = $this->share(function () use ($core) { $serviceName = $core->getConfiguration()->getBorder(); $configuration = $core->getConfiguration()->getService($serviceName); diff --git a/lib/classes/recordutils/image.class.php b/lib/classes/recordutils/image.class.php index 0d19200d2b..7d187e13b0 100644 --- a/lib/classes/recordutils/image.class.php +++ b/lib/classes/recordutils/image.class.php @@ -10,6 +10,13 @@ */ use Symfony\Component\Process\ProcessBuilder; +use PHPExiftool\Reader; +use Imagine\Image\ImagineInterface; +use Imagine\Image\Color; +use Imagine\Image\Box; +use Imagine\Image\Point; + +// use Imagine\Image\ImageInterface; /** * @@ -29,39 +36,61 @@ class recordutils_image extends recordutils * @param int $width * @return Array */ - protected function wrap($fontSize, $angle, $fontFace, $string, $width) + protected function wrap(&$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)); } /** @@ -73,18 +102,23 @@ class recordutils_image extends recordutils */ public static function stamp(\media_subdef $subdef) { - $ColorToArray = function($attr, $ret = array(255, 255, 255, 0)) { + $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 <= 127 || ($i < 3 && $v < 256))) { + if ($v >= 0 && ($v <= 100 || ($i < 3 && $v < 256))) { $ret[$i] = $v; } } - return($ret); + $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(); @@ -101,56 +135,90 @@ class recordutils_image extends recordutils return $subdef->get_pathfile(); } + $rotation = NULL; + try { + $reader = new Reader(); + $metadatas = $reader + ->files($subdef->get_pathfile()) + ->first()->getMetadatas(); + $r = $metadatas['IFD0:Orientation']; + if ($r) + $rotation = trim($r->getValue()); + } 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(); - - $vars = $xpprefs->query('/baseprefs/stamp/*/var'); - for ($i = 0; $i < $vars->length; $i++) { - if (strtoupper($vars->item($i)->getAttribute('name')) == 'DATE') { - @unlink($pathOut); // no cache possible when date changes - break; - } - } - - // get from cache - if (is_file($pathOut)) { - return $pathOut; - } - - $logofile = $registry->get('GV_RootPath') . 'config/stamp/' . $base_id; - $logo_phywidth = $logo_phyheight = 0; // physical size - - if (is_array($logosize = @getimagesize($logofile))) { - $logo_phywidth = $logosize[0]; - $logo_phyheight = $logosize[1]; - } - - $pathTmpStamp = $registry->get('GV_RootPath') . 'tmp/' . time() . '-stamptmp_' . $subdef->get_file(); $stampNodes = $xpprefs->query('/baseprefs/stamp'); if ($stampNodes->length == 0) { return $subdef->get_pathfile(); } - if (!($tailleimg = @getimagesize($pathIn))) { - return false; + + $pathIn = $subdef->get_path() . $subdef->get_file(); + $pathOut = $subdef->get_path() . 'stamp_' . $subdef->get_file(); + + $vars = $xpprefs->query('/baseprefs/stamp/*/var'); + + // 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; + } } - $image_width = $tailleimg[0]; - $image_height = $tailleimg[1]; + // get from cache ? + if (is_file($pathOut)) { + return $pathOut; + } - $builder = ProcessBuilder::create(array($registry->get('convert_binary'))); + // open the document + $image_in = $imagine->open($pathIn); + $image_size = $image_in->getSize(); + switch ($rotation) { + case 6: + $image_width = $image_size->getHeight(); + $image_height = $image_size->getWidth(); + $image_in->rotate(90); + $rotation = '90'; + break; + case 8: + $image_width = $image_size->getHeight(); + $image_height = $image_size->getWidth(); + $image_in->rotate(270); + break; + case 3: + $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; + } + + // open the logo + $logo_phywidth = $logo_phyheight = 0; // physical 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(); + } $tables = array( 'TOP' => array('h' => 0, 'rows' => array()), @@ -162,13 +230,14 @@ class recordutils_image extends recordutils for ($istamp = 0; $istamp < $stampNodes->length; $istamp++) { $stamp = $stampNodes->item($istamp); - $stamp_background = $ColorToArray($stamp->getAttribute('background'), array(255, 255, 255, 0)); + $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 = ''; @@ -187,6 +256,7 @@ class recordutils_image extends recordutils $n->parentNode->replaceChild($domprefs->createTextNode($varval), $n); } + // replace "field" nodes with their values $fields = $xpprefs->query('*/field', $stamp); for ($i = 0; $i < $fields->length; $i++) { $fldval = ''; @@ -209,8 +279,8 @@ class recordutils_image extends recordutils $text_width = $image_width; $logopos = null; - $imlogo = null; // gd image + // compute logo position / size $logo_reswidth = 0; $logo_resheight = 0; if ($logo_phywidth > 0 && $logo_phyheight > 0) { @@ -229,40 +299,27 @@ class recordutils_image extends recordutils ($logo_reswidth / $logo_phywidth)); } - 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; - } + if ($logopos == 'LEFT' || $logopos == 'RIGHT') { - if ($imlogo) { - 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 -= $logo_reswidth; - if ($logopos == 'LEFT') { - $logo_xpos = 0; - $text_xpos = $logo_reswidth; - } else { // RIGHT - $text_xpos = 0; - $logo_xpos = ($image_width - $logo_reswidth); - } + 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 -= $logo_reswidth; + if ($logopos == 'LEFT') { + $logo_xpos = 0; + $text_xpos = $logo_reswidth; + } else { // RIGHT + $text_xpos = 0; + $logo_xpos = ($image_width - $logo_reswidth); } } } } + + // compute text blocks $txth = 0; $txtblock = array(); $texts = $xpprefs->query('text', $stamp); @@ -275,7 +332,6 @@ class recordutils_image extends recordutils $tmpfontsize = (int) $tmpfontsize; $fontsize = $tmpfontsize; } - $txtColor = $ColorToArray($texts->item($i)->getAttribute('color'), array(0, 0, 0, 0)); if ($fontsize < 2) $fontsize = 2; @@ -285,22 +341,15 @@ class recordutils_image extends recordutils $txtline = $texts->item($i)->nodeValue; if ($txtline != '') { - $txtlines = recordutils_image::wrap( - $fontsize, 0, __DIR__ . '/arial.ttf', $txtline, $text_width + $wrap = recordutils_image::wrap($imagine, $fontsize, 0, __DIR__ . '/arial.ttf', $txtline, $text_width ); - - foreach ($txtlines['l'] as $txtline) { - $txtblock[] = array( - 'x' => $text_xpos, - 'dy' => $txtlines['dy'], - 'w' => $text_width, - 'h' => $txtlines['h'], - 't' => $txtline, - 's' => $fontsize, - 'k' => $txtColor - ); - $txth += $txtlines['h']; - } + $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']; } } @@ -314,78 +363,56 @@ class recordutils_image extends recordutils if ($stampheight <= 0) { continue; } - $imfg = imagecreatetruecolor($image_width, $stampheight); - imagesavealpha($imfg, true); - imagelayereffect($imfg, IMG_EFFECT_REPLACE); - $trans_colour = imagecolorallocatealpha($imfg, 0, 0, 0, 127); - imagefilledrectangle($imfg, 0, 0, $image_width, $stampheight, $trans_colour); - imagecolordeallocate($imfg, $trans_colour); - if ($imlogo) { + // create the block + $imfg = $imagine->create(new Box($image_width, $stampheight), $stamp_background); + + // copy the logo + if ($logo_reswidth > 0 && $logo_resheight > 0) { if ($logo_reswidth != $logo_phywidth) { - imagecopyresampled($imfg, $imlogo, $logo_xpos, 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 - ); + $imfg->paste( + $logo_obj->copy()->resize(new Box($logo_reswidth, $logo_resheight)) + , new Point($logo_xpos, 0)); } else { - imagecopy($imfg, $imlogo, $logo_xpos, 0, // dst_x, dst_y - 0, 0, // src_x, src_y - $logo_phywidth, // src_w - $logo_phyheight // src_h - ); + $imfg->paste($logo_obj, new Point($logo_xpos, 0)); } } - if (count($txtblock) >= 0) { - $txt_ypos = 0; //$txtblock[0]['h']; - foreach ($txtblock as $block) { - $k = $block['k']; - $color = imagecolorallocatealpha($imfg, $k[0], $k[1], $k[2], $k[3]); - imagettftext($imfg, $block['s'], 0, $block['x'], $txt_ypos - $block['dy'], $color, __DIR__ . '/arial.ttf', $block['t']); - $txt_ypos += $block['h']; - imagecolordeallocate($imfg, $color); + // 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']; } } - imagepng($imfg, $pathTmpStamp . '_' . $istamp . 'fg.png'); - imagedestroy($imfg); - - $bgfile = null; - if ($stamp_background[3] != 127) { // no need if background is transparent - $imbg = imagecreatetruecolor($image_width, $stampheight); - imagesavealpha($imbg, true); - imagelayereffect($imbg, IMG_EFFECT_REPLACE); - $trans_colour = imagecolorallocatealpha($imbg, $stamp_background[0], $stamp_background[1], $stamp_background[2], $stamp_background[3]); - imagefilledrectangle($imbg, 0, 0, $image_width, $stampheight, $trans_colour); - imagecolordeallocate($imbg, $trans_colour); - - imagepng($imbg, $pathTmpStamp . '_' . $istamp . 'bg.png'); - imagedestroy($imbg); - - $bgfile = $pathTmpStamp . '_' . $istamp . 'bg.png'; - } - + // memo into one of the 4 buffer $tables[$stamp_position]['rows'][] = array( - 'x0' => 0, - 'y0' => $tables[$stamp_position]['h'], - 'w' => $image_width, - 'h' => $stampheight, - 'bgfile' => $bgfile, - 'fgfile' => $pathTmpStamp . '_' . $istamp . 'fg.png' + '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']; - if ($newh != $image_height) { - $builder->add('-extent') - ->add($image_width . 'x' . $newh . '+0-' . $tables['TOP']['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']; } @@ -396,34 +423,17 @@ class recordutils_image extends recordutils $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) { - if ($row['bgfile']) { - $builder->add('-draw') - ->add('image Over ' . $row['x0'] . ',' . $row['y0'] . ' ' . $row['w'] . ',' . $row['h'] . ' "' . $row['bgfile'] . '"'); - } - $builder->add('-draw') - ->add('image Over ' . $row['x0'] . ',' . $row['y0'] . ' ' . $row['w'] . ',' . $row['h'] . ' "' . $row['fgfile'] . '"'); + $image_out->paste($row['img'], new Point($row['x0'], $row['y0'])); } } } - $builder->add($pathIn) - ->add($pathOut); - - $process = $builder->getProcess(); - - $process->run(); - - foreach (array('TOP', 'TOP-OVER', 'BOTTOM-OVER', 'BOTTOM') as $ta) { - foreach ($tables[$ta]['rows'] as $row) { - if ($row['bgfile']) { - @unlink($row['bgfile']); - } - @unlink($row['fgfile']); - } - } + // save the output + $image_out->save($pathOut); if (is_file($pathOut)) { return $pathOut; @@ -432,14 +442,20 @@ class recordutils_image extends recordutils return $subdef->get_pathfile(); } - /** + + + /** * * @param \media_subdef $subdef * @return boolean|string */ public static function watermark(\media_subdef $subdef) { - $appbox = appbox::get_instance(\bootstrap::getCore()); + $Core = \bootstrap::getCore(); + + $imagine = $Core['imagine']; + $appbox = appbox::get_instance($Core); + $registry = $appbox->get_registry(); $base_id = $subdef->get_record()->get_base_id(); @@ -452,66 +468,80 @@ class recordutils_image extends recordutils } if (!$subdef->is_physically_present()) { - return $subdef->get_pathfile(); + 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 ($registry->get('composite_binary') && - file_exists($registry->get('GV_RootPath') . '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( - $registry->get('composite_binary'), - $registry->get('GV_RootPath') . 'config/wm/' . $base_id, - $pathIn, - '-strip', '-watermark', '90%', '-gravity', 'center', - $pathOut - )); + $wm_file = $registry->get('GV_RootPath') . 'config/wm/' . $base_id; + if (0 && 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 ($registry->get('convert_binary')) { - $collname = phrasea::bas_names($base_id); - $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); - - if ($tailleText < 8) - $tailleText = 8; - - if ($tailleText > 12) - $decalage = 2; - else - $decalage = 1; - - $builder = ProcessBuilder::create(array( - $registry->get('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(); + $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); + + $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()); + + $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); + + $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; } From 5121fe275f2ef5ccc34615a65a05c11d76362d80 Mon Sep 17 00:00:00 2001 From: jygaulier Date: Tue, 12 Mar 2013 17:08:35 +0100 Subject: [PATCH 3/4] fix : debug removed --- lib/classes/recordutils/image.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/classes/recordutils/image.class.php b/lib/classes/recordutils/image.class.php index 7d187e13b0..7f1f3824d4 100644 --- a/lib/classes/recordutils/image.class.php +++ b/lib/classes/recordutils/image.class.php @@ -490,7 +490,7 @@ class recordutils_image extends recordutils $in_h = $in_size->getHeight(); $wm_file = $registry->get('GV_RootPath') . 'config/wm/' . $base_id; - if (0 && file_exists($wm_file)) { + if (file_exists($wm_file)) { $wm_image = $imagine->open($wm_file); $wm_size = $wm_image->getSize(); $wm_w = $wm_size->getWidth(); From 360c09c3fd5324ffaa22c16d3a886128e6d0f45e Mon Sep 17 00:00:00 2001 From: jygaulier Date: Wed, 13 Mar 2013 16:10:00 +0100 Subject: [PATCH 4/4] CS --- lib/classes/recordutils/image.class.php | 117 ++++++++++++------------ 1 file changed, 56 insertions(+), 61 deletions(-) diff --git a/lib/classes/recordutils/image.class.php b/lib/classes/recordutils/image.class.php index 7f1f3824d4..92f000489c 100644 --- a/lib/classes/recordutils/image.class.php +++ b/lib/classes/recordutils/image.class.php @@ -9,8 +9,9 @@ * file that was distributed with this source code. */ -use Symfony\Component\Process\ProcessBuilder; -use PHPExiftool\Reader; +// use Symfony\Component\Process\ProcessBuilder; +// use PHPExiftool\Reader; +use MediaVorus\Media\Media; use Imagine\Image\ImagineInterface; use Imagine\Image\Color; use Imagine\Image\Box; @@ -36,7 +37,7 @@ class recordutils_image extends recordutils * @param int $width * @return Array */ - protected function wrap(&$imagine, $fontSize, $angle, $fontFace, $string, $width) + protected function wrap(ImagineInterface $imagine, $fontSize, $angle, $fontFace, $string, $width) { // str 'Op' used to calculate linespace $font = $imagine->font($fontFace, $fontSize, new Color("000000", 0)); @@ -58,7 +59,7 @@ class recordutils_image extends recordutils 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 => ''); + $twords[++$iword] = array(($part = 0) => '', 1 => ''); } if (!ctype_space($c) && $part == 0) { $part++; @@ -135,15 +136,13 @@ class recordutils_image extends recordutils return $subdef->get_pathfile(); } - $rotation = NULL; + $rotation = null; try { - $reader = new Reader(); - $metadatas = $reader - ->files($subdef->get_pathfile()) - ->first()->getMetadatas(); - $r = $metadatas['IFD0:Orientation']; - if ($r) - $rotation = trim($r->getValue()); + $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 } @@ -189,18 +188,18 @@ class recordutils_image extends recordutils $image_in = $imagine->open($pathIn); $image_size = $image_in->getSize(); switch ($rotation) { - case 6: + case MediaVorus\Media\Image::ORIENTATION_90: $image_width = $image_size->getHeight(); $image_height = $image_size->getWidth(); $image_in->rotate(90); $rotation = '90'; break; - case 8: + case MediaVorus\Media\Image::ORIENTATION_270: $image_width = $image_size->getHeight(); $image_height = $image_size->getWidth(); $image_in->rotate(270); break; - case 3: + case MediaVorus\Media\Image::ORIENTATION_180: $image_width = $image_size->getWidth(); $image_height = $image_size->getHeight(); $image_in->rotate(180); @@ -442,9 +441,7 @@ class recordutils_image extends recordutils return $subdef->get_pathfile(); } - - - /** + /** * * @param \media_subdef $subdef * @return boolean|string @@ -485,59 +482,57 @@ class recordutils_image extends recordutils } $in_image = $imagine->open($pathIn); - $in_size = $in_image->getSize(); + $in_size = $in_image->getSize(); $in_w = $in_size->getWidth(); $in_h = $in_size->getHeight(); $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(); + $wm_image = $imagine->open($wm_file); + $wm_size = $wm_image->getSize(); + $wm_w = $wm_size->getWidth(); + $wm_h = $wm_size->getHeight(); - 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); + 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); - $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); + $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); - $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()); + $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()); - $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); + $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); - $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); - } + $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);