111 protected $imageFileExt = [
'gif',
'jpg',
'jpeg',
'png',
'tif',
'bmp',
'tga',
'pcx',
'ai',
'pdf'];
238 'aqua' => [0, 255, 255],
239 'black' => [0, 0, 0],
240 'blue' => [0, 0, 255],
241 'fuchsia' => [255, 0, 255],
242 'gray' => [128, 128, 128],
243 'green' => [0, 128, 0],
244 'lime' => [0, 255, 0],
245 'maroon' => [128, 0, 0],
246 'navy' => [0, 0, 128],
247 'olive' => [128, 128, 0],
248 'purple' => [128, 0, 128],
249 'red' => [255, 0, 0],
250 'silver' => [192, 192, 192],
251 'teal' => [0, 128, 128],
252 'yellow' => [255, 255, 0],
253 'white' => [255, 255, 255]
307 $gfxConf =
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'];
308 if (function_exists(
'imagecreatefromjpeg') && function_exists(
'imagejpeg')) {
309 $this->gdlibExtensions[] =
'jpg';
310 $this->gdlibExtensions[] =
'jpeg';
312 if (function_exists(
'imagecreatefrompng') && function_exists(
'imagepng')) {
313 $this->gdlibExtensions[] =
'png';
315 if (function_exists(
'imagecreatefromgif') && function_exists(
'imagegif')) {
316 $this->gdlibExtensions[] =
'gif';
319 if ($gfxConf[
'processor_colorspace'] && in_array($gfxConf[
'processor_colorspace'], $this->allowedColorSpaceNames,
true)) {
320 $this->colorspace = $gfxConf[
'processor_colorspace'];
323 $this->processorEnabled = (bool)$gfxConf[
'processor_enabled'];
326 $this->addFrameSelection = (bool)$gfxConf[
'processor_allowFrameSelection'];
327 if ($gfxConf[
'gdlib_png']) {
328 $this->gifExtension =
'png';
330 $this->imageFileExt = GeneralUtility::trimExplode(
',', $gfxConf[
'imagefile_ext']);
335 $this->cmds[
'jpg'] = $this->cmds[
'jpeg'] =
'-colorspace ' . $this->colorspace .
' -quality ' .
$this->jpegQuality;
338 if ($gfxConf[
'processor_effects']) {
339 $this->processorEffectsEnabled =
true;
344 $this->mayScaleUp = (bool)$gfxConf[
'processor_allowUpscaling'];
345 $this->csConvObj = GeneralUtility::makeInstance(CharsetConverter::class);
351 public function init()
353 trigger_error(
'GraphicalFunctions->init() will be removed in TYPO3 v10.0. Simply remove the call to the method, since this is now evaluted in the constructor.', E_USER_DEPRECATED);
354 $gfxConf =
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'];
355 if (function_exists(
'imagecreatefromjpeg') && function_exists(
'imagejpeg')) {
356 $this->gdlibExtensions[] =
'jpg';
357 $this->gdlibExtensions[] =
'jpeg';
359 if (function_exists(
'imagecreatefrompng') && function_exists(
'imagepng')) {
360 $this->gdlibExtensions[] =
'png';
362 if (function_exists(
'imagecreatefromgif') && function_exists(
'imagegif')) {
363 $this->gdlibExtensions[] =
'gif';
366 if ($gfxConf[
'processor_colorspace'] && in_array($gfxConf[
'processor_colorspace'], $this->allowedColorSpaceNames,
true)) {
367 $this->colorspace = $gfxConf[
'processor_colorspace'];
370 $this->processorEnabled = (bool)$gfxConf[
'processor_enabled'];
373 $this->addFrameSelection = (bool)$gfxConf[
'processor_allowFrameSelection'];
374 if ($gfxConf[
'gdlib_png']) {
375 $this->gifExtension =
'png';
377 $this->imageFileExt = GeneralUtility::trimExplode(
',', $gfxConf[
'imagefile_ext']);
382 $this->cmds[
'jpg'] = $this->cmds[
'jpeg'] =
'-colorspace ' . $this->colorspace .
' -quality ' .
$this->jpegQuality;
385 if ($gfxConf[
'processor_effects']) {
386 $this->processorEffectsEnabled =
true;
391 $this->mayScaleUp = (bool)$gfxConf[
'processor_allowUpscaling'];
392 $this->csConvObj = GeneralUtility::makeInstance(CharsetConverter::class);
412 if ($conf[
'file'] && $conf[
'mask']) {
413 $imgInf = pathinfo($conf[
'file']);
414 $imgExt = strtolower($imgInf[
'extension']);
415 if (!in_array($imgExt, $this->gdlibExtensions,
true)) {
420 $maskInf = pathinfo($conf[
'mask']);
421 $maskExt = strtolower($maskInf[
'extension']);
422 if (!in_array($maskExt, $this->gdlibExtensions,
true)) {
427 if ($BBimage && $BBmask) {
436 $destImg = imagecreatetruecolor(
$w,
$h);
438 if ($this->saveAlphaLayer) {
439 imagesavealpha($destImg,
true);
440 $Bcolor = imagecolorallocatealpha($destImg, 0, 0, 0, 127);
441 imagefill($destImg, 0, 0, $Bcolor);
443 $Bcolor = imagecolorallocate($destImg, 0, 0, 0);
444 imagefilledrectangle($destImg, 0, 0,
$w,
$h, $Bcolor);
448 imagedestroy($cpImg);
449 imagedestroy($destImg);
452 $destImg = imagecreatetruecolor(
$w,
$h);
453 if ($this->saveAlphaLayer) {
454 imagesavealpha($destImg,
true);
455 $Bcolor = imagecolorallocatealpha($destImg, 0, 0, 0, 127);
456 imagefill($destImg, 0, 0, $Bcolor);
458 $Bcolor = imagecolorallocate($destImg, 0, 0, 0);
459 imagefilledrectangle($destImg, 0, 0,
$w,
$h, $Bcolor);
463 imagedestroy($cpImg);
464 imagedestroy($destImg);
468 $this->
combineExec($theDest, $theImage, $theMask, $theDest);
473 if (!$this->saveAlphaLayer) {
474 imagecolortransparent($backIm, -1);
497 if (!in_array($conf[
'BBOX'][2], $this->gdlibExtensions,
true)) {
499 $conf[
'file'] = $conf[
'BBOX'][3];
503 imagedestroy($cpImg);
518 $cpW = imagesx($cpImg);
519 $cpH = imagesy($cpImg);
520 $tile = GeneralUtility::intExplode(
',', $conf[
'tile']);
524 for ($xt = 0; $xt < $tile[0]; $xt++) {
525 $Xstart = $cpOff[0] + $cpW * $xt;
535 $w = $cpW - $cpImgCutX;
542 for ($yt = 0; $yt < $tile[1]; $yt++) {
543 $Ystart = $cpOff[1] + $cpH * $yt;
552 $h = $cpH - $cpImgCutY;
595 public function imagecopyresized(&$dstImg, $srcImg, $dstX, $dstY, $srcX, $srcY, $dstWidth, $dstHeight, $srcWidth, $srcHeight)
597 if (!$this->saveAlphaLayer) {
599 $tmpImg = imagecreatetruecolor(imagesx($dstImg), imagesy($dstImg));
601 imagecopyresized($tmpImg, $dstImg, 0, 0, 0, 0, imagesx($dstImg), imagesy($dstImg), imagesx($dstImg), imagesy($dstImg));
603 imagecopyresized($tmpImg, $srcImg, $dstX, $dstY, $srcX, $srcY, $dstWidth, $dstHeight, $srcWidth, $srcHeight);
607 imagecopyresized($dstImg, $srcImg, $dstX, $dstY, $srcX, $srcY, $dstWidth, $dstHeight, $srcWidth, $srcHeight);
630 $theText = $conf[
'text'];
631 if ($conf[
'imgMap'] && is_array($conf[
'imgMap.'])) {
634 if (!$conf[
'hideButCreateMap']) {
638 if (!$conf[
'niceText']) {
639 $Fcolor = imagecolorallocate(
$im, $cols[0], $cols[1], $cols[2]);
641 $Fcolor = $conf[
'antiAlias'] ? $Fcolor : -$Fcolor;
642 for ($a = 0; $a < $conf[
'iterations']; $a++) {
644 if ($spacing || $wordSpacing) {
645 $this->
SpacedImageTTFText(
$im, $conf[
'fontSize'], $conf[
'angle'], $txtPos[0], $txtPos[1], $Fcolor, GeneralUtility::getFileAbsFileName($conf[
'fontFile']), $theText, $spacing, $wordSpacing, $conf[
'splitRendering.']);
647 $this->
renderTTFText(
$im, $conf[
'fontSize'], $conf[
'angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf[
'fontFile'], $theText, $conf[
'splitRendering.'], $conf);
661 $newW = ceil($sF * imagesx(
$im));
662 $newH = ceil($sF * imagesy(
$im));
664 $maskImg = imagecreatetruecolor($newW, $newH);
665 $Bcolor = imagecolorallocate($maskImg, 255, 255, 255);
666 imagefilledrectangle($maskImg, 0, 0, $newW, $newH, $Bcolor);
667 $Fcolor = imagecolorallocate($maskImg, 0, 0, 0);
669 if ($spacing || $wordSpacing) {
670 $this->
SpacedImageTTFText($maskImg, $conf[
'fontSize'], $conf[
'angle'], $txtPos[0], $txtPos[1], $Fcolor, GeneralUtility::getFileAbsFileName($conf[
'fontFile']), $theText, $spacing, $wordSpacing, $conf[
'splitRendering.'], $sF);
672 $this->
renderTTFText($maskImg, $conf[
'fontSize'], $conf[
'angle'], $txtPos[0], $txtPos[1], $Fcolor, $conf[
'fontFile'], $theText, $conf[
'splitRendering.'], $conf, $sF);
675 imagedestroy($maskImg);
677 if (!$this->processorEffectsEnabled) {
678 $command = trim($this->scalecmd .
' ' .
$w .
'x' .
$h .
'! -negate');
680 $command = trim($conf[
'niceText.'][
'before'] .
' ' . $this->scalecmd .
' ' .
$w .
'x' .
$h .
'! ' . $conf[
'niceText.'][
'after'] .
' -negate');
681 if ($conf[
'niceText.'][
'sharpen']) {
682 $command .= $this->
v5_sharpen($conf[
'niceText.'][
'sharpen']);
687 $colorImg = imagecreatetruecolor(
$w,
$h);
688 $Ccolor = imagecolorallocate($colorImg, $cols[0], $cols[1], $cols[2]);
689 imagefilledrectangle($colorImg, 0, 0,
$w,
$h, $Ccolor);
691 imagedestroy($colorImg);
695 $this->
combineExec($fileMenu, $fileColor, $fileMask, $fileMenu);
700 if (!$this->saveAlphaLayer) {
701 imagecolortransparent($backIm, -1);
725 $angle = (int)$conf[
'angle'] / 180 * M_PI;
734 switch ($conf[
'align']) {
738 $factor = abs(cos($angle));
739 $sign = cos($angle) < 0 ? -1 : 1;
740 $len1 = $sign * $factor * $straightBB[0];
741 $len2 = $sign * $BB[0];
742 $result[0] =
$w - ceil($len2 * $factor + (1 - $factor) * $len1);
743 $factor = abs(sin($angle));
744 $sign = sin($angle) < 0 ? -1 : 1;
745 $len1 = $sign * $factor * $straightBB[0];
746 $len2 = $sign * $BB[1];
747 $result[1] = ceil($len2 * $factor + (1 - $factor) * $len1);
750 switch ($conf[
'align']) {
754 $result[0] = round($result[0] / 2);
755 $result[1] = round($result[1] / 2);
761 $result = $this->
applyOffset($result, GeneralUtility::intExplode(
',', $conf[
'offset']));
778 $theText = $conf[
'text'];
779 $charInf = $this->
ImageTTFBBoxWrapper($conf[
'fontSize'], $conf[
'angle'], $conf[
'fontFile'], $theText, $conf[
'splitRendering.'], $sF);
780 $theBBoxInfo = $charInf;
781 if ($conf[
'angle']) {
782 $xArr = [$charInf[0], $charInf[2], $charInf[4], $charInf[6]];
783 $yArr = [$charInf[1], $charInf[3], $charInf[5], $charInf[7]];
784 $x = max($xArr) - min($xArr);
785 $y = max($yArr) - min($yArr);
787 $x = $charInf[2] - $charInf[0];
788 $y = $charInf[1] - $charInf[7];
791 $theBBoxInfo[
'lineHeight'] = $y;
792 if (!empty($conf[
'lineHeight'])) {
793 $theBBoxInfo[
'lineHeight'] = (int)$conf[
'lineHeight'];
797 if ($spacing || $wordSpacing) {
799 if (!$spacing && $wordSpacing) {
800 $bits = explode(
' ', $theText);
801 foreach ($bits as $word) {
803 $wordInf = $this->
ImageTTFBBoxWrapper($conf[
'fontSize'], $conf[
'angle'], $conf[
'fontFile'], $word, $conf[
'splitRendering.'], $sF);
804 $wordW = $wordInf[2] - $wordInf[0];
805 $x += $wordW + $wordSpacing;
808 $utf8Chars = $this->csConvObj->utf8_to_numberarray($theText);
810 foreach ($utf8Chars as $char) {
811 $charInf = $this->
ImageTTFBBoxWrapper($conf[
'fontSize'], $conf[
'angle'], $conf[
'fontFile'], $char, $conf[
'splitRendering.'], $sF);
812 $charW = $charInf[2] - $charInf[0];
813 $x += $charW + ($char ===
' ' ? $wordSpacing : $spacing);
816 } elseif (isset($conf[
'breakWidth']) && $conf[
'breakWidth'] && $this->
getRenderedTextWidth($conf[
'text'], $conf) > $conf[
'breakWidth']) {
819 $breakWidth = $conf[
'breakWidth'];
823 foreach ($wordPairs as $index => $wordPair) {
825 if ($index == 0 || $currentWidth + $wordWidth <= $breakWidth) {
826 $currentWidth += $wordWidth;
828 $maxWidth = max($maxWidth, $currentWidth);
831 $currentWidth = $wordWidth;
834 $x = max($maxWidth, $currentWidth) * $sF;
839 if (is_array($theBBoxInfo)) {
840 foreach ($theBBoxInfo as &$value) {
841 $value = ceil($value / $sF);
846 return [$x, $y, $theBBoxInfo];
859 $this->map .=
'<area' .
' shape="poly"' .
' coords="' . implode(
',', $cords) .
'"'
860 .
' href="' . htmlspecialchars($conf[
'url']) .
'"'
861 . ($conf[
'target'] ?
' target="' . htmlspecialchars($conf[
'target']) .
'"' :
'')
862 . ((
string)$conf[
'titleText'] !==
'' ?
' title="' . htmlspecialchars($conf[
'titleText']) .
'"' :
'')
863 .
' alt="' . htmlspecialchars($conf[
'altText']) .
'" />';
878 $pars = GeneralUtility::intExplode(
',', $conf[
'explode'] .
',');
879 $newCords[0] = $cords[0] + $offset[0] - $pars[0];
880 $newCords[1] = $cords[1] + $offset[1] + $pars[1];
881 $newCords[2] = $cords[2] + $offset[0] + $pars[0];
882 $newCords[3] = $cords[3] + $offset[1] + $pars[1];
883 $newCords[4] = $cords[4] + $offset[0] + $pars[0];
884 $newCords[5] = $cords[5] + $offset[1] - $pars[1];
885 $newCords[6] = $cords[6] + $offset[0] - $pars[0];
886 $newCords[7] = $cords[7] + $offset[1] - $pars[1];
909 public function SpacedImageTTFText(&
$im, $fontSize, $angle, $x, $y, $Fcolor, $fontFile, $text, $spacing, $wordSpacing, $splitRenderingConf, $sF = 1)
913 if (!$spacing && $wordSpacing) {
914 $bits = explode(
' ', $text);
915 foreach ($bits as $word) {
917 $wordInf = $this->
ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $word, $splitRenderingConf, $sF);
918 $wordW = $wordInf[2] - $wordInf[0];
920 $x += $wordW + $wordSpacing;
923 $utf8Chars = $this->csConvObj->utf8_to_numberarray($text);
925 foreach ($utf8Chars as $char) {
926 $charInf = $this->
ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $char, $splitRenderingConf, $sF);
927 $charW = $charInf[2] - $charInf[0];
929 $x += $charW + ($char ===
' ' ? $wordSpacing : $spacing);
945 $maxWidth = (int)$conf[
'maxWidth'];
949 if ($spacing || $wordSpacing) {
950 return $conf[
'fontSize'];
954 $bounds = $this->
ImageTTFBBoxWrapper($conf[
'fontSize'], $conf[
'angle'], $conf[
'fontFile'], $conf[
'text'], $conf[
'splitRendering.']);
955 if ($conf[
'angle'] < 0) {
956 $pixelWidth = abs($bounds[4] - $bounds[0]);
957 } elseif ($conf[
'angle'] > 0) {
958 $pixelWidth = abs($bounds[2] - $bounds[6]);
960 $pixelWidth = abs($bounds[4] - $bounds[6]);
963 if ($pixelWidth <= $maxWidth) {
967 }
while ($conf[
'fontSize'] > 1);
969 return $conf[
'fontSize'];
983 public function ImageTTFBBoxWrapper($fontSize, $angle, $fontFile, $string, $splitRendering, $sF = 1)
987 $stringParts = $this->
splitString($string, $splitRendering, $fontSize, $fontFile);
989 foreach ($stringParts as $strCfg) {
990 $fontFile = GeneralUtility::getFileAbsFileName($strCfg[
'fontFile']);
991 if (is_readable($fontFile)) {
995 if (empty($offsetInfo)) {
999 $offsetInfo[2] += $calc[2] - $calc[0] + (int)$splitRendering[
'compX'] + (
int)$strCfg[
'xSpaceBefore'] + (int)$strCfg[
'xSpaceAfter'];
1000 $offsetInfo[3] += $calc[3] - $calc[1] - (int)$splitRendering[
'compY'] - (
int)$strCfg[
'ySpaceBefore'] - (int)$strCfg[
'ySpaceAfter'];
1001 $offsetInfo[4] += $calc[4] - $calc[6] + (int)$splitRendering[
'compX'] + (
int)$strCfg[
'xSpaceBefore'] + (int)$strCfg[
'xSpaceAfter'];
1002 $offsetInfo[5] += $calc[5] - $calc[7] - (int)$splitRendering[
'compY'] - (
int)$strCfg[
'ySpaceBefore'] - (int)$strCfg[
'ySpaceAfter'];
1005 debug(
'cannot read file: ' . $fontFile, self::class .
'::ImageTTFBBoxWrapper()');
1025 public function ImageTTFTextWrapper(
$im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering, $sF = 1)
1028 $stringParts = $this->
splitString($string, $splitRendering, $fontSize, $fontFile);
1029 $x = ceil($sF * $x);
1030 $y = ceil($sF * $y);
1032 foreach ($stringParts as $i => $strCfg) {
1034 $colorIndex = $color;
1036 if ($strCfg[
'color'] && $sF == 1) {
1038 $colorIndex = imagecolorallocate(
$im, $cols[0], $cols[1], $cols[2]);
1039 $colorIndex = $color >= 0 ? $colorIndex : -$colorIndex;
1043 $x += (int)$strCfg[
'xSpaceBefore'];
1044 $y -= (int)$strCfg[
'ySpaceBefore'];
1046 $fontFile = GeneralUtility::getFileAbsFileName($strCfg[
'fontFile']);
1047 if (is_readable($fontFile)) {
1052 $x += $wordInf[2] - $wordInf[0] + (int)$splitRendering[
'compX'] + (
int)$strCfg[
'xSpaceAfter'];
1053 $y += $wordInf[5] - $wordInf[7] - (int)$splitRendering[
'compY'] - (
int)$strCfg[
'ySpaceAfter'];
1055 debug(
'cannot read file: ' . $fontFile, self::class .
'::ImageTTFTextWrapper()');
1069 public function splitString($string, $splitRendering, $fontSize, $fontFile)
1075 'fontSize' => $fontSize,
1076 'fontFile' => $fontFile
1080 if (is_array($splitRendering)) {
1083 foreach ($sKeyArray as $key) {
1084 $cfg = $splitRendering[$key .
'.'];
1086 switch ((
string)$splitRendering[$key]) {
1087 case 'highlightWord':
1088 if ((
string)$cfg[
'value'] !==
'') {
1091 foreach ($result as $part) {
1093 $explodedParts = explode($cfg[
'value'], $part[
'str']);
1094 foreach ($explodedParts as $c => $expValue) {
1095 if ((
string)$expValue !==
'') {
1096 $newResult[] = array_merge($part, [
'str' => $expValue]);
1098 if ($c + 1 < count($explodedParts)) {
1100 'str' => $cfg[
'value'],
1101 'fontSize' => $cfg[
'fontSize'] ? $cfg[
'fontSize'] : $part[
'fontSize'],
1102 'fontFile' => $cfg[
'fontFile'] ? $cfg[
'fontFile'] : $part[
'fontFile'],
1103 'color' => $cfg[
'color'],
1104 'xSpaceBefore' => $cfg[
'xSpaceBefore'],
1105 'xSpaceAfter' => $cfg[
'xSpaceAfter'],
1106 'ySpaceBefore' => $cfg[
'ySpaceBefore'],
1107 'ySpaceAfter' => $cfg[
'ySpaceAfter']
1113 if (!empty($newResult)) {
1114 $result = $newResult;
1119 if ((
string)$cfg[
'value'] !==
'') {
1121 $ranges = GeneralUtility::trimExplode(
',', $cfg[
'value'],
true);
1122 foreach ($ranges as $i => $rangeDef) {
1123 $ranges[$i] = GeneralUtility::intExplode(
'-', $ranges[$i]);
1124 if (!isset($ranges[$i][1])) {
1125 $ranges[$i][1] = $ranges[$i][0];
1130 foreach ($result as $part) {
1135 $utf8Chars = $this->csConvObj->utf8_to_numberarray($part[
'str']);
1136 foreach ($utf8Chars as $utfChar) {
1138 $uNumber = (int)$this->csConvObj->utf8CharToUnumber($utfChar);
1140 foreach ($ranges as $rangeDef) {
1141 if ($uNumber >= $rangeDef[0] && (!$rangeDef[1] || $uNumber <= $rangeDef[1])) {
1146 if ($currentState == -1) {
1147 $currentState = $inRange;
1151 if ($inRange != $currentState && $uNumber !== 9 && $uNumber !== 10 && $uNumber !== 13 && $uNumber !== 32) {
1153 if ($bankAccum !==
'') {
1155 'str' => $bankAccum,
1156 'fontSize' => $currentState && $cfg[
'fontSize'] ? $cfg[
'fontSize'] : $part[
'fontSize'],
1157 'fontFile' => $currentState && $cfg[
'fontFile'] ? $cfg[
'fontFile'] : $part[
'fontFile'],
1158 'color' => $currentState ? $cfg[
'color'] :
'',
1159 'xSpaceBefore' => $currentState ? $cfg[
'xSpaceBefore'] :
'',
1160 'xSpaceAfter' => $currentState ? $cfg[
'xSpaceAfter'] :
'',
1161 'ySpaceBefore' => $currentState ? $cfg[
'ySpaceBefore'] :
'',
1162 'ySpaceAfter' => $currentState ? $cfg[
'ySpaceAfter'] :
''
1166 $currentState = $inRange;
1170 $bankAccum .= $utfChar;
1173 if ($bankAccum !==
'') {
1175 'str' => $bankAccum,
1176 'fontSize' => $currentState && $cfg[
'fontSize'] ? $cfg[
'fontSize'] : $part[
'fontSize'],
1177 'fontFile' => $currentState && $cfg[
'fontFile'] ? $cfg[
'fontFile'] : $part[
'fontFile'],
1178 'color' => $currentState ? $cfg[
'color'] :
'',
1179 'xSpaceBefore' => $currentState ? $cfg[
'xSpaceBefore'] :
'',
1180 'xSpaceAfter' => $currentState ? $cfg[
'xSpaceAfter'] :
'',
1181 'ySpaceBefore' => $currentState ? $cfg[
'ySpaceBefore'] :
'',
1182 'ySpaceAfter' => $currentState ? $cfg[
'ySpaceAfter'] :
''
1187 if (!empty($newResult)) {
1188 $result = $newResult;
1209 $spacing = (int)$conf[
'spacing'];
1210 $wordSpacing = (int)$conf[
'wordSpacing'];
1211 $wordSpacing = $wordSpacing ?: $spacing * 2;
1212 $spacing *= $scaleFactor;
1213 $wordSpacing *= $scaleFactor;
1214 return [$spacing, $wordSpacing];
1226 if (!$conf[
'niceText']) {
1250 protected function renderTTFText(&
$im, $fontSize, $angle, $x, $y, $color, $fontFile, $string, $splitRendering, $conf, $sF = 1)
1252 if (isset($conf[
'breakWidth']) && $conf[
'breakWidth'] && $this->
getRenderedTextWidth($string, $conf) > $conf[
'breakWidth']) {
1255 $breakWidth = $conf[
'breakWidth'];
1259 foreach ($wordPairs as $index => $wordPair) {
1261 if ($index == 0 || $currentWidth + $wordWidth <= $breakWidth) {
1262 $currentWidth += $wordWidth;
1263 $phrase .= $wordPair;
1270 $currentWidth = $wordWidth;
1271 $phrase = $wordPair;
1275 if ($currentWidth) {
1292 $wordsArray = preg_split(
'#([- .,!:]+)#', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
1293 $wordsCount = count($wordsArray);
1294 for ($index = 0; $index < $wordsCount; $index += 2) {
1295 $wordPairs[] = $wordsArray[$index] . $wordsArray[$index + 1];
1309 $bounds = $this->
ImageTTFBBoxWrapper($conf[
'fontSize'], $conf[
'angle'], $conf[
'fontFile'], $text, $conf[
'splitRendering.']);
1310 if ($conf[
'angle'] < 0) {
1311 $pixelWidth = abs($bounds[4] - $bounds[0]);
1312 } elseif ($conf[
'angle'] > 0) {
1313 $pixelWidth = abs($bounds[2] - $bounds[6]);
1315 $pixelWidth = abs($bounds[4] - $bounds[6]);
1327 protected function getBreakSpace($conf, array $boundingBox =
null)
1329 if (!isset($boundingBox)) {
1331 $boundingBox = $boundingBox[2];
1333 if (isset($conf[
'breakSpace']) && $conf[
'breakSpace']) {
1334 $breakSpace = $boundingBox[
'lineHeight'] * $conf[
'breakSpace'];
1336 $breakSpace = $boundingBox[
'lineHeight'];
1357 $thickness = (int)$conf[
'thickness'];
1359 $txtConf[
'fontColor'] = $conf[
'color'];
1361 for ($b = 1; $b <= $outLineDist; $b++) {
1368 for ($a = 0; $a < $it; $a++) {
1388 if ($distance && $iterations) {
1389 for ($a = 0; $a < $iterations; $a++) {
1390 $yOff = round(sin(2 * M_PI / $iterations * ($a + 1)) * 100 * $distance);
1392 $yOff = (int)(ceil(abs($yOff / 100)) * ($yOff / abs($yOff)));
1394 $xOff = round(cos(2 * M_PI / $iterations * ($a + 1)) * 100 * $distance);
1396 $xOff = (int)(ceil(abs($xOff / 100)) * ($xOff / abs($xOff)));
1398 $res[$a] = [$xOff, $yOff];
1415 $conf[
'color'] = $conf[
'highColor'];
1417 $newOffset = GeneralUtility::intExplode(
',', $conf[
'offset']);
1418 $newOffset[0] *= -1;
1419 $newOffset[1] *= -1;
1420 $conf[
'offset'] = implode(
',', $newOffset);
1421 $conf[
'color'] = $conf[
'lowColor'];
1440 if (!$blurRate || !$this->processorEffectsEnabled) {
1441 $txtConf[
'fontColor'] = $conf[
'color'];
1453 $blurColImg = imagecreatetruecolor(
$w,
$h);
1455 $Bcolor = imagecolorallocate($blurColImg, $bcols[0], $bcols[1], $bcols[2]);
1456 imagefilledrectangle($blurColImg, 0, 0,
$w,
$h, $Bcolor);
1458 imagedestroy($blurColImg);
1460 $blurTextImg = imagecreatetruecolor(
$w + $blurBorder * 2,
$h + $blurBorder * 2);
1462 $Bcolor = imagecolorallocate($blurTextImg, 0, 0, 0);
1463 imagefilledrectangle($blurTextImg, 0, 0,
$w + $blurBorder * 2,
$h + $blurBorder * 2, $Bcolor);
1464 $txtConf[
'fontColor'] =
'white';
1465 $blurBordArr = [$blurBorder, $blurBorder];
1470 imagedestroy($blurTextImg);
1471 $command = $this->
v5_blur($blurRate + 1);
1476 if ($blurTextImg_tmp) {
1478 $blurTextImg = imagecreatetruecolor(
$w,
$h);
1481 imagedestroy($blurTextImg_tmp);
1484 if ($conf[
'intensity']) {
1487 $intensity = ceil(255 - $intensity / 100 * 255);
1490 if ($opacity && $opacity < 100) {
1491 $high = ceil(255 * $opacity / 100);
1498 imagedestroy($blurTextImg);
1502 $this->
combineExec($fileMenu, $fileColor, $fileMask, $fileMenu);
1507 if (!$this->saveAlphaLayer) {
1508 imagecolortransparent($backIm, -1);
1535 $cords = GeneralUtility::intExplode(
',', $conf[
'dimensions'] .
',,,');
1536 $conf[
'offset'] = $cords[0] .
',' . $cords[1];
1540 if (isset($conf[
'opacity'])) {
1545 $opacity = abs($opacity - 100);
1546 $opacity = round(127 * $opacity / 100);
1548 $tmpColor = imagecolorallocatealpha(
$im, $cols[0], $cols[1], $cols[2], $opacity);
1549 imagefilledrectangle(
$im, $cords[0], $cords[1], $cords[0] + $cords[2] - 1, $cords[1] + $cords[3] - 1, $tmpColor);
1574 $ellipseConfiguration = GeneralUtility::intExplode(
',', $conf[
'dimensions'] .
',,,');
1576 $conf[
'offset'] = $ellipseConfiguration[0] .
',' . $ellipseConfiguration[1];
1578 $imageCoordinates = $this->
objPosition($conf,
$workArea, [$ellipseConfiguration[2], $ellipseConfiguration[3]]);
1580 $fillingColor = imagecolorallocate(
$im, $color[0], $color[1], $color[2]);
1581 imagefilledellipse(
$im, $imageCoordinates[0], $imageCoordinates[1], $imageCoordinates[2], $imageCoordinates[3], $fillingColor);
1594 $commands = $this->
IMparams($conf[
'value']);
1613 $effects = explode(
'|',
$setup);
1615 foreach ($effects as $val) {
1616 $pairs = explode(
'=', $val, 2);
1617 $value = trim($pairs[1]);
1618 $effect = strtolower(trim($pairs[0]));
1621 $commands .=
' -gamma ' . (float)$value;
1624 if ($this->processorEffectsEnabled) {
1625 $commands .= $this->
v5_blur($value);
1629 if ($this->processorEffectsEnabled) {
1643 $params = GeneralUtility::intExplode(
',', $value);
1650 $commands .=
' -colorspace GRAY';
1656 $commands .=
' -emboss';
1659 $commands .=
' -flip';
1662 $commands .=
' -flop';
1671 $commands .=
' -negate';
1691 $effects = explode(
'|',
$setup);
1692 foreach ($effects as $val) {
1693 $pairs = explode(
'=', $val, 2);
1694 $value = trim($pairs[1]);
1695 $effect = strtolower(trim($pairs[0]));
1699 $params = GeneralUtility::intExplode(
',', $value);
1702 case 'outputlevels':
1703 $params = GeneralUtility::intExplode(
',', $value);
1724 $cords = GeneralUtility::intExplode(
',', $conf[
'crop'] .
',,,');
1725 $conf[
'offset'] = $cords[0] .
',' . $cords[1];
1726 $cords = $this->
objPosition($conf, $this->workArea, [$cords[2], $cords[3]]);
1727 $newIm = imagecreatetruecolor($cords[2], $cords[3]);
1728 $cols = $this->
convertColor($conf[
'backColor'] ?: $this->setup[
'backColor']);
1729 $Bcolor = imagecolorallocate($newIm, $cols[0], $cols[1], $cols[2]);
1730 imagefilledrectangle($newIm, 0, 0, $cords[2], $cords[3], $Bcolor);
1733 if ($cords[0] < 0) {
1736 $newConf[
'offset'] = -$cords[0];
1738 if ($cords[1] < 0) {
1741 $newConf[
'offset'] .=
',' . -$cords[1];
1745 $this->w = imagesx(
$im);
1746 $this->h = imagesy(
$im);
1760 if ($conf[
'width'] || $conf[
'height'] || $conf[
'params']) {
1764 $theNewFile = $this->
imageMagickConvert($theFile, $this->gifExtension, $conf[
'width'], $conf[
'height'], $conf[
'params']);
1769 $this->w = imagesx(
$im);
1770 $this->h = imagesy(
$im);
1775 if ($theNewFile[3] && $theNewFile[3] != $theFile) {
1776 unlink($theNewFile[3]);
1791 $this->workArea = GeneralUtility::intExplode(
',',
$workArea);
1792 $this->workArea = $this->
applyOffset($this->workArea, $this->OFFSET);
1793 if (!$this->workArea[2]) {
1796 if (!$this->workArea[3]) {
1813 $totalCols = imagecolorstotal(
$im);
1815 for ($c = 0; $c < $totalCols; $c++) {
1816 $cols = imagecolorsforindex(
$im, $c);
1817 $grayArr[] = round(($cols[
'red'] + $cols[
'green'] + $cols[
'blue']) / 3);
1819 $min = min($grayArr);
1820 $max = max($grayArr);
1821 $delta = $max - $min;
1823 for ($c = 0; $c < $totalCols; $c++) {
1824 $cols = imagecolorsforindex(
$im, $c);
1825 $cols[
'red'] = floor(($cols[
'red'] - $min) / $delta * 255);
1826 $cols[
'green'] = floor(($cols[
'green'] - $min) / $delta * 255);
1827 $cols[
'blue'] = floor(($cols[
'blue'] - $min) / $delta * 255);
1828 imagecolorset(
$im, $c, $cols[
'red'], $cols[
'green'], $cols[
'blue']);
1849 $high = 255 - $temp;
1851 $delta = $high - $low;
1852 $totalCols = imagecolorstotal(
$im);
1853 for ($c = 0; $c < $totalCols; $c++) {
1854 $cols = imagecolorsforindex(
$im, $c);
1855 $cols[
'red'] = $low + floor($cols[
'red'] / 255 * $delta);
1856 $cols[
'green'] = $low + floor($cols[
'green'] / 255 * $delta);
1857 $cols[
'blue'] = $low + floor($cols[
'blue'] / 255 * $delta);
1858 imagecolorset(
$im, $c, $cols[
'red'], $cols[
'green'], $cols[
'blue']);
1875 $delta = $high - $low;
1876 $totalCols = imagecolorstotal(
$im);
1877 for ($c = 0; $c < $totalCols; $c++) {
1878 $cols = imagecolorsforindex(
$im, $c);
1882 imagecolorset(
$im, $c, $cols[
'red'], $cols[
'green'], $cols[
'blue']);
1896 $fI = GeneralUtility::split_fileref($file);
1897 $ext = strtolower($fI[
'fileext']);
1901 $params =
' -colors ' . $reduce;
1902 if ($reduce <= 256) {
1903 $params .=
' -type Palette';
1905 $prefix = $ext ===
'png' && $reduce <= 256 ?
'png8:' :
'';
1930 $sharpenArr = explode(
',',
',' . $this->im5fx_sharpenSteps);
1931 $sharpenF = trim($sharpenArr[$factor]);
1933 return ' -sharpen ' . $sharpenF;
1949 $blurArr = explode(
',',
',' . $this->im5fx_blurSteps);
1950 $blurF = trim($blurArr[$factor]);
1952 return ' -blur ' . $blurF;
1979 $cords[0] = (int)$cords[0] + (
int)
$OFFSET[0];
1980 $cords[1] = (int)$cords[1] + (
int)
$OFFSET[1];
1994 $cParts = explode(
':', $string, 2);
1996 $string = $cParts[0];
1997 if (strstr($string,
'#')) {
1998 $string = preg_replace(
'/[^A-Fa-f0-9]*/',
'', $string);
1999 $col[] = hexdec(substr($string, 0, 2));
2000 $col[] = hexdec(substr($string, 2, 2));
2001 $col[] = hexdec(substr($string, 4, 2));
2002 } elseif (strstr($string,
',')) {
2003 $string = preg_replace(
'/[^,0-9]*/',
'', $string);
2004 $strArr = explode(
',', $string);
2005 $col[] = (int)$strArr[0];
2006 $col[] = (int)$strArr[1];
2007 $col[] = (int)$strArr[2];
2009 $string = strtolower(trim($string));
2010 if ($this->colMap[$string]) {
2011 $col = $this->colMap[$string];
2017 if (trim($cParts[1])) {
2018 $cParts[1] = trim($cParts[1]);
2019 if ($cParts[1][0] ===
'*') {
2020 $val = (float)substr($cParts[1], 1);
2025 $val = (int)$cParts[1];
2048 $result[2] = $BB[0];
2049 $result[3] = $BB[1];
2052 $align = explode(
',', $conf[
'align']);
2053 $align[0] = strtolower(substr(trim($align[0]), 0, 1));
2054 $align[1] = strtolower(substr(trim($align[1]), 0, 1));
2055 switch ($align[0]) {
2057 $result[0] =
$w - $result[2];
2060 $result[0] = round((
$w - $result[2]) / 2);
2065 switch ($align[1]) {
2068 $result[1] =
$h - $result[3];
2071 $result[1] = round((
$h - $result[3]) / 2);
2076 $result = $this->
applyOffset($result, GeneralUtility::intExplode(
',', $conf[
'offset']));
2100 public function imageMagickConvert($imagefile, $newExt =
'',
$w =
'',
$h =
'', $params =
'', $frame =
'', $options = [], $mustCreate =
false)
2102 if (!$this->processorEnabled) {
2111 $newExt = strtolower(trim($newExt));
2116 if ($newExt ===
'web') {
2117 if (in_array($info[2], $this->webImageExt,
true)) {
2120 $newExt = $this->
gif_or_jpg($info[2], $info[0], $info[1]);
2122 $params = $this->cmds[$newExt];
2126 if (!in_array($newExt, $this->imageFileExt,
true)) {
2131 $w = $data[
'origW'];
2132 $h = $data[
'origH'];
2138 $noScale = !
$w && !
$h || $data[0] == $info[0] && $data[1] == $info[1] || !empty($options[
'noScale']);
2139 if ($noScale && !$data[
'crs'] && !$params && !$frame && $newExt == $info[2] && !$mustCreate) {
2142 if (!empty($options[
'noScale'])) {
2143 $info[0] = $data[0];
2144 $info[1] = $data[1];
2146 $info[3] = $imagefile;
2149 $info[0] = $data[0];
2150 $info[1] = $data[1];
2151 $frame = $this->addFrameSelection ? (int)$frame :
'';
2153 $params = $this->cmds[$newExt];
2157 if (!$data[
'origW']) {
2158 $data[
'origW'] = $data[0];
2160 if (!$data[
'origH']) {
2161 $data[
'origH'] = $data[1];
2163 $offsetX = (int)(($data[0] - $data[
'origW']) * ($data[
'cropH'] + 100) / 200);
2164 $offsetY = (int)(($data[1] - $data[
'origH']) * ($data[
'cropV'] + 100) / 200);
2165 $params .=
' -crop ' . $data[
'origW'] .
'x' . $data[
'origH'] .
'+' . $offsetX .
'+' . $offsetY .
'! +repage';
2167 $command = $this->scalecmd .
' ' . $info[0] .
'x' . $info[1] .
'! ' . $params .
' ';
2170 $cropscale = $data[
'crs'] ?
'crs-V' . $data[
'cropV'] .
'H' . $data[
'cropH'] :
'';
2171 if ($this->alternativeOutputKey) {
2172 $theOutputName = GeneralUtility::shortMD5($command . $cropscale .
PathUtility::basename($imagefile) . $this->alternativeOutputKey .
'[' . $frame .
']');
2174 $theOutputName = GeneralUtility::shortMD5($command . $cropscale . $imagefile . filemtime($imagefile) .
'[' . $frame .
']');
2176 if ($this->imageMagickConvert_forceFileNameBody) {
2178 $this->imageMagickConvert_forceFileNameBody =
'';
2183 if ($this->dontCheckForExistingTempFile || !file_exists(
$output)) {
2193 if ($info[2] == $this->gifExtension && !$this->dontCompress) {
2212 preg_match(
'/([^\\.]*)$/', $imageFile, $reg);
2213 if (file_exists($imageFile) && in_array(strtolower($reg[0]), $this->imageFileExt,
true)) {
2216 $imageInfoObject = GeneralUtility::makeInstance(ImageInfo::class, $imageFile);
2217 if ($imageInfoObject->getWidth()) {
2219 $imageInfoObject->getWidth(),
2220 $imageInfoObject->getHeight(),
2221 strtolower($reg[0]),
2240 $filePath = $identifyResult[3];
2245 $cache = GeneralUtility::makeInstance(CacheManager::class)->getCache(
'cache_imagesizes');
2246 $imageDimensions = [
2247 'hash' => $statusHash,
2248 'imagewidth' => $identifyResult[0],
2249 'imageheight' => $identifyResult[1],
2251 $cache->set($identifier, $imageDimensions);
2269 $cache = GeneralUtility::makeInstance(CacheManager::class)->getCache(
'cache_imagesizes');
2270 $cachedImageDimensions = $cache->get($identifier);
2271 if (!isset($cachedImageDimensions[
'hash'])) {
2275 if ($cachedImageDimensions[
'hash'] !== $statusHash) {
2277 $cache->remove($identifier);
2280 preg_match(
'/([^\\.]*)$/', $filePath, $imageExtension);
2282 (int)$cachedImageDimensions[
'imagewidth'],
2283 (
int)$cachedImageDimensions[
'imageheight'],
2284 strtolower($imageExtension[0]),
2303 return sha1($filePath);
2315 $fileStatus = stat($filePath);
2317 return sha1($fileStatus[
'mtime'] . $fileStatus[
'size']);
2333 if (strstr(
$w .
$h,
'm')) {
2338 if (strstr(
$w .
$h,
'c')) {
2339 $out[
'cropH'] = (int)substr(strstr(
$w,
'c'), 1);
2340 $out[
'cropV'] = (int)substr(strstr(
$h,
'c'), 1);
2349 if (!empty($options[
'maxW'])) {
2352 if (
$w > $options[
'maxW']) {
2353 $w = $options[
'maxW'];
2358 if ($info[0] > $options[
'maxW']) {
2359 $w = $options[
'maxW'];
2365 if (!empty($options[
'maxH'])) {
2368 if (
$h > $options[
'maxH']) {
2369 $h = $options[
'maxH'];
2375 if ($info[1] > $options[
'maxH']) {
2376 $h = $options[
'maxH'];
2382 $out[
'origW'] =
$w;
2383 $out[
'origH'] =
$h;
2385 if (!$this->mayScaleUp) {
2386 if (
$w > $info[0]) {
2389 if (
$h > $info[1]) {
2394 if ((
$w ||
$h) && $info[0] && $info[1]) {
2396 $info[1] = ceil($info[1] * (
$w / $info[0]));
2400 $info[0] = ceil($info[0] * (
$h / $info[1]));
2405 $ratio = $info[0] / $info[1];
2406 if (
$h * $ratio >
$w) {
2407 $h = round(
$w / $ratio);
2409 $w = round(
$h * $ratio);
2413 $ratio = $info[0] / $info[1];
2414 if (
$h * $ratio <
$w) {
2415 $h = round(
$w / $ratio);
2417 $w = round(
$h * $ratio);
2427 if (isset($options[
'minW']) && $out[0] < $options[
'minW']) {
2428 if (($max || $crs) && $out[0]) {
2429 $out[1] = round($out[1] * $options[
'minW'] / $out[0]);
2431 $out[0] = $options[
'minW'];
2433 if (isset($options[
'minH']) && $out[1] < $options[
'minH']) {
2434 if (($max || $crs) && $out[1]) {
2435 $out[0] = round($out[0] * $options[
'minH'] / $out[1]);
2437 $out[1] = $options[
'minH'];
2455 if (!$this->processorEnabled) {
2461 [$width, $height, $fileExtension, $fileType] = explode(
' ', $result);
2462 if ((
int)$width && (
int)$height) {
2463 return [$width, $height, strtolower($fileExtension), $imagefile, strtolower($fileType)];
2477 $frame = $this->addFrameSelection ? 0 :
null;
2484 $result = array_pop($returnVal);
2485 $this->IM_commands[] = [
'identify', $cmd, $result];
2501 if (!$this->processorEnabled) {
2506 $frame = $this->addFrameSelection ? (int)$frame :
null;
2513 $this->IM_commands[] = [
$output, $cmd];
2516 GeneralUtility::fixPermissions(
$output);
2532 if (!$this->processorEnabled) {
2539 $parameters =
'-compose over'
2540 .
' -quality ' . $this->jpegQuality
2547 $this->IM_commands[] = [
$output, $cmd];
2550 GeneralUtility::fixPermissions(
$output);
2551 if (is_file($theMask)) {
2577 $gfxConf =
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'];
2578 if (!$gfxConf[
'gif_compress'] || strtolower(substr($theFile, -4, 4)) !==
'.gif') {
2582 if (($type ===
'IM' || !$type) && $gfxConf[
'processor_enabled'] && $gfxConf[
'processor_path_lzw']) {
2586 if (@rename($theFile, $temporaryName)) {
2590 $gfxConf[
'processor_path_lzw']
2593 unlink($temporaryName);
2596 if (@is_file($theFile)) {
2597 GeneralUtility::fixPermissions($theFile);
2599 } elseif (($type ===
'GD' || !$type) && $gfxConf[
'gdlib'] && !$gfxConf[
'gdlib_png']) {
2600 $tempImage = imagecreatefromgif($theFile);
2601 imagegif($tempImage, $theFile);
2602 imagedestroy($tempImage);
2604 if (@is_file($theFile)) {
2605 GeneralUtility::fixPermissions($theFile);
2622 public static function readPngGif($theFile, $output_png =
false)
2624 if (!
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'processor_enabled'] || !@is_file($theFile)) {
2628 $ext = strtolower(substr($theFile, -4, 4));
2629 if ((
string)$ext ===
'.png' && $output_png || (
string)$ext ===
'.gif' && !$output_png) {
2636 $newFile =
Environment::getPublicPath() .
'/typo3temp/assets/images/' . md5($theFile .
'|' . filemtime($theFile)) . ($output_png ?
'.png' :
'.gif');
2640 $GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'processor_path']
2643 if (@is_file($newFile)) {
2644 GeneralUtility::fixPermissions($newFile);
2672 $this->w = imagesx(
$im);
2673 $this->h = imagesy(
$im);
2689 if ($type ===
'ai' ||
$w * $h < $this->pixelLimitGif) {
2704 public function output($file)
2708 preg_match(
'/([^\\.]*)$/', $file, $reg);
2709 $ext = strtolower($reg[0]);
2715 if ($this->setup[
'reduceColors']) {
2718 @copy($reduced, $file);
2731 if ($this->setup[
'quality']) {
2748 imagedestroy($this->im);
2757 public function imgTag($imgInfo)
2759 return '<img src="' . $imgInfo[3] .
'" width="' . $imgInfo[0] .
'" height="' . $imgInfo[1] .
'" border="0" alt="" />';
2771 public function ImageWrite($destImg, $theImage, $quality = 0)
2773 imageinterlace($destImg, 0);
2774 $ext = strtolower(substr($theImage, strrpos($theImage,
'.') + 1));
2779 if (function_exists(
'imagejpeg')) {
2780 if ($quality === 0) {
2783 $result = imagejpeg($destImg, $theImage, $quality);
2787 if (function_exists(
'imagegif')) {
2788 imagetruecolortopalette($destImg,
true, 256);
2789 $result = imagegif($destImg, $theImage);
2793 if (function_exists(
'imagepng')) {
2794 $result = imagepng($destImg, $theImage);
2799 GeneralUtility::fixPermissions($theImage);
2813 $imgInf = pathinfo($sourceImg);
2814 $ext = strtolower($imgInf[
'extension']);
2817 if (function_exists(
'imagecreatefromgif')) {
2818 return imagecreatefromgif($sourceImg);
2822 if (function_exists(
'imagecreatefrompng')) {
2823 $imageHandle = imagecreatefrompng($sourceImg);
2824 if ($this->saveAlphaLayer) {
2825 imagesavealpha($imageHandle,
true);
2827 return $imageHandle;
2832 if (function_exists(
'imagecreatefromjpeg')) {
2833 return imagecreatefromjpeg($sourceImg);
2838 $imageInfo = GeneralUtility::makeInstance(ImageInfo::class, $sourceImg);
2839 $im = imagecreatetruecolor($imageInfo->getWidth(), $imageInfo->getHeight());
2840 $Bcolor = imagecolorallocate(
$im, 128, 128, 128);
2841 imagefilledrectangle(
$im, 0, 0, $imageInfo->getWidth(), $imageInfo->getHeight(), $Bcolor);
2853 $r = dechex($color[0]);
2854 if (strlen($r) < 2) {
2857 $g = dechex($color[1]);
2858 if (strlen($g) < 2) {
2861 $b = dechex($color[2]);
2862 if (strlen($b) < 2) {
2865 return '#' . $r . $g . $b;
2876 public function unifyColors(&$img, $colArr, $closest =
false)
2879 if (is_array($colArr) && !empty($colArr) && function_exists(
'imagepng') && function_exists(
'imagecreatefrompng')) {
2880 $firstCol = array_shift($colArr);
2882 $origName = $preName = $this->
randomName() .
'.png';
2885 if (count($colArr) > 1) {
2887 $firstCol = $this->
hexColor($firstColArr);
2888 foreach ($colArr as $transparentColor) {
2889 $transparentColor = $this->
convertColor($transparentColor);
2890 $transparentColor = $this->
hexColor($transparentColor);
2891 $cmd =
'-fill "' . $firstCol .
'" -opaque "' . $transparentColor .
'"';
2893 $preName = $postName;
2896 if (@is_file($origName)) {
2905 $retCol = imagecolorclosest($img, $firstColArr[0], $firstColArr[1], $firstColArr[2]);
2907 $retCol = imagecolorexact($img, $firstColArr[0], $firstColArr[1], $firstColArr[2]);
2934 if (empty(
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'gdlib'])) {
2935 throw new \RuntimeException(
'TYPO3 Fatal Error: No gdlib. ' . $textline1 .
' ' . $textline2 .
' ' . $textline3, 1270853952);
2939 if (!empty(
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'gdlib_png'])) {
2940 $im = imagecreatefrompng($basePath .
'NotFound.png');
2942 $im = imagecreatefromgif($basePath .
'NotFound.gif');
2945 $white = imagecolorallocate(
$im, 255, 255, 255);
2946 $black = imagecolorallocate(
$im, 0, 0, 0);
2951 imagefilledrectangle(
$im, $x, 9, 56, 16, $white);
2952 imagestring(
$im, $font, $x, 9, $textline1, $black);
2955 imagefilledrectangle(
$im, $x, 19, 56, 26, $white);
2956 imagestring(
$im, $font, $x, 19, $textline2, $black);
2959 imagefilledrectangle(
$im, $x, 29, 56, 36, $white);
2960 imagestring(
$im, $font, $x, 29, substr($textline3, -14), $black);
2963 if (!empty(
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'gdlib_png'])) {
2964 imagepng(
$im, $filename);
2966 imagegif(
$im, $filename);
2979 return $fontSize / 96.0 * 72;