‪TYPO3CMS  9.5
LocalCropScaleMaskHelper.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
22 
27 {
31  protected ‪$processor;
32 
37  {
38  $this->processor = ‪$processor;
39  }
40 
60  public function ‪process(‪TaskInterface $task)
61  {
62  $result = null;
63  $targetFile = $task->‪getTargetFile();
64  $sourceFile = $task->‪getSourceFile();
65 
66  $originalFileName = $sourceFile->‪getForLocalProcessing(false);
67  $gifBuilder = GeneralUtility::makeInstance(GifBuilder::class);
68 
69  $configuration = $targetFile->getProcessingConfiguration();
70  $configuration['additionalParameters'] = $this->‪modifyImageMagickStripProfileParameters($configuration['additionalParameters'], $configuration);
71 
72  if (empty($configuration['fileExtension'])) {
73  $configuration['fileExtension'] = $task->‪getTargetFileExtension();
74  }
75 
76  $options = $this->‪getConfigurationForImageCropScaleMask($targetFile, $gifBuilder);
77 
78  $croppedImage = null;
79  if (!empty($configuration['crop'])) {
80 
81  // check if it is a json object
82  $cropData = json_decode($configuration['crop']);
83  if ($cropData) {
84  $crop = implode(',', [(int)$cropData->x, (int)$cropData->y, (int)$cropData->width, (int)$cropData->height]);
85  } else {
86  $crop = $configuration['crop'];
87  }
88 
89  list($offsetLeft, $offsetTop, $newWidth, $newHeight) = explode(',', $crop, 4);
90 
91  $backupPrefix = $gifBuilder->filenamePrefix;
92  $gifBuilder->filenamePrefix = 'crop_';
93 
94  $jpegQuality = ‪MathUtility::forceIntegerInRange(‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['jpg_quality'], 10, 100, 85);
95 
96  // the result info is an array with 0=width,1=height,2=extension,3=filename
97  $result = $gifBuilder->imageMagickConvert(
98  $originalFileName,
99  $configuration['fileExtension'],
100  '',
101  '',
102  sprintf('-crop %dx%d+%d+%d +repage -quality %d', $newWidth, $newHeight, $offsetLeft, $offsetTop, $jpegQuality),
103  '',
104  ['noScale' => true],
105  true
106  );
107  $gifBuilder->filenamePrefix = $backupPrefix;
108 
109  if ($result !== null) {
110  $originalFileName = $croppedImage = $result[3];
111  }
112  }
113 
114  // Normal situation (no masking)
115  if (!(is_array($configuration['maskImages']) && ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_enabled'])) {
116 
117  // SVG
118  if ($croppedImage === null && $sourceFile->getExtension() === 'svg') {
119  $newDimensions = $this->‪getNewSvgDimensions($sourceFile, $configuration, $options, $gifBuilder);
120  $result = [
121  0 => $newDimensions['width'],
122  1 => $newDimensions['height'],
123  3 => '' // no file = use original
124  ];
125  } else {
126  // all other images
127  // the result info is an array with 0=width,1=height,2=extension,3=filename
128  $result = $gifBuilder->imageMagickConvert(
129  $originalFileName,
130  $configuration['fileExtension'],
131  $configuration['width'],
132  $configuration['height'],
133  $configuration['additionalParameters'],
134  $configuration['frame'],
135  $options
136  );
137  }
138  } else {
139  $targetFileName = $this->‪getFilenameForImageCropScaleMask($task);
140  $temporaryFileName = ‪Environment::getPublicPath() . '/typo3temp/' . $targetFileName;
141  $maskImage = $configuration['maskImages']['maskImage'];
142  $maskBackgroundImage = $configuration['maskImages']['backgroundImage'];
143  if ($maskImage instanceof Resource\‪FileInterface && $maskBackgroundImage instanceof Resource\‪FileInterface) {
144  $temporaryExtension = 'png';
145  if (!‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_allowTemporaryMasksAsPng']) {
146  // If ImageMagick version 5+
147  $temporaryExtension = $gifBuilder->gifExtension;
148  }
149  $tempFileInfo = $gifBuilder->imageMagickConvert(
150  $originalFileName,
151  $temporaryExtension,
152  $configuration['width'],
153  $configuration['height'],
154  $configuration['additionalParameters'],
155  $configuration['frame'],
156  $options
157  );
158  if (is_array($tempFileInfo)) {
159  $maskBottomImage = $configuration['maskImages']['maskBottomImage'];
160  if ($maskBottomImage instanceof Resource\‪FileInterface) {
161  $maskBottomImageMask = $configuration['maskImages']['maskBottomImageMask'];
162  } else {
163  $maskBottomImageMask = null;
164  }
165 
166  // Scaling: ****
167  $tempScale = [];
168  $command = '-geometry ' . $tempFileInfo[0] . 'x' . $tempFileInfo[1] . '!';
169  $command = $this->‪modifyImageMagickStripProfileParameters($command, $configuration);
170  $tmpStr = $gifBuilder->randomName();
171  // m_mask
172  $tempScale['m_mask'] = $tmpStr . '_mask.' . $temporaryExtension;
173  $gifBuilder->imageMagickExec($maskImage->getForLocalProcessing(true), $tempScale['m_mask'], $command);
174  // m_bgImg
175  $tempScale['m_bgImg'] = $tmpStr . '_bgImg.miff';
176  $gifBuilder->imageMagickExec($maskBackgroundImage->getForLocalProcessing(), $tempScale['m_bgImg'], $command);
177  // m_bottomImg / m_bottomImg_mask
178  if ($maskBottomImage instanceof Resource\‪FileInterface && $maskBottomImageMask instanceof Resource\‪FileInterface) {
179  $tempScale['m_bottomImg'] = $tmpStr . '_bottomImg.' . $temporaryExtension;
180  $gifBuilder->imageMagickExec($maskBottomImage->getForLocalProcessing(), $tempScale['m_bottomImg'], $command);
181  $tempScale['m_bottomImg_mask'] = ($tmpStr . '_bottomImg_mask.') . $temporaryExtension;
182  $gifBuilder->imageMagickExec($maskBottomImageMask->getForLocalProcessing(), $tempScale['m_bottomImg_mask'], $command);
183  // BEGIN combining:
184  // The image onto the background
185  $gifBuilder->combineExec($tempScale['m_bgImg'], $tempScale['m_bottomImg'], $tempScale['m_bottomImg_mask'], $tempScale['m_bgImg']);
186  }
187  // The image onto the background
188  $gifBuilder->combineExec($tempScale['m_bgImg'], $tempFileInfo[3], $tempScale['m_mask'], $temporaryFileName);
189  $tempFileInfo[3] = $temporaryFileName;
190  // Unlink the temp-images...
191  foreach ($tempScale as $tempFile) {
192  if (@is_file($tempFile)) {
193  unlink($tempFile);
194  }
195  }
196  }
197  $result = $tempFileInfo;
198  }
199  }
200 
201  // check if the processing really generated a new file (scaled and/or cropped)
202  if ($result !== null) {
203  if ($result[3] !== $originalFileName || $originalFileName === $croppedImage) {
204  $result = [
205  'width' => $result[0],
206  'height' => $result[1],
207  'filePath' => $result[3],
208  ];
209  } else {
210  // No file was generated
211  $result = null;
212  }
213  }
214 
215  // Cleanup temp file if it isn't used as result
216  if ($croppedImage && ($result === null || $croppedImage !== $result['filePath'])) {
217  GeneralUtility::unlink_tempfile($croppedImage);
218  }
219 
220  return $result;
221  }
222 
233  protected function ‪getNewSvgDimensions($file, array $configuration, array $options, ‪GifBuilder $gifBuilder)
234  {
235  $info = [$file->getProperty('width'), $file->getProperty('height')];
236  $data = $gifBuilder->‪getImageScale($info, $configuration['width'], $configuration['height'], $options);
237 
238  // Turn cropScaling into scaling
239  if ($data['crs']) {
240  if (!$data['origW']) {
241  $data['origW'] = $data[0];
242  }
243  if (!$data['origH']) {
244  $data['origH'] = $data[1];
245  }
246  if ($data[0] > $data['origW']) {
247  $data[1] = (int)(($data['origW'] * $data[1]) / $data[0]);
248  $data[0] = $data['origW'];
249  } else {
250  $data[0] = (int)(($data['origH'] * $data[0]) / $data[1]);
251  $data[1] = $data['origH'];
252  }
253  }
254 
255  return [
256  'width' => $data[0],
257  'height' => $data[1]
258  ];
259  }
260 
267  protected function ‪getConfigurationForImageCropScaleMask(Resource\‪ProcessedFile $processedFile, \‪TYPO3\CMS\Frontend\Imaging\‪GifBuilder $gifBuilder)
268  {
269  $configuration = $processedFile->getProcessingConfiguration();
270 
271  if ($configuration['useSample']) {
272  $gifBuilder->scalecmd = '-sample';
273  }
274  $options = [];
275  if ($configuration['maxWidth']) {
276  $options['maxW'] = $configuration['maxWidth'];
277  }
278  if ($configuration['maxHeight']) {
279  $options['maxH'] = $configuration['maxHeight'];
280  }
281  if ($configuration['minWidth']) {
282  $options['minW'] = $configuration['minWidth'];
283  }
284  if ($configuration['minHeight']) {
285  $options['minH'] = $configuration['minHeight'];
286  }
287 
288  $options['noScale'] = $configuration['noScale'];
289 
290  return $options;
291  }
292 
299  protected function ‪getFilenameForImageCropScaleMask(‪TaskInterface $task)
300  {
301  $configuration = $task->‪getTargetFile()->‪getProcessingConfiguration();
302  $targetFileExtension = $task->‪getSourceFile()->‪getExtension();
303  $processedFileExtension = ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] ? 'png' : 'gif';
304  if (is_array($configuration['maskImages']) && ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_enabled'] && $task->‪getSourceFile()->‪getExtension() != $processedFileExtension) {
305  $targetFileExtension = 'jpg';
306  } elseif ($configuration['fileExtension']) {
307  $targetFileExtension = $configuration['fileExtension'];
308  }
309 
310  return $task->‪getTargetFile()->‪generateProcessedFileNameWithoutExtension() . '.' . ltrim(trim($targetFileExtension), '.');
311  }
312 
320  protected function ‪modifyImageMagickStripProfileParameters($parameters, array $configuration)
321  {
322  // Strips profile information of image to save some space:
323  if (isset($configuration['stripProfile'])) {
324  if (
325  $configuration['stripProfile']
326  && ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_stripColorProfileCommand'] !== ''
327  ) {
328  $parameters = ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_stripColorProfileCommand'] . $parameters;
329  } else {
330  $parameters .= '###SkipStripProfile###';
331  }
332  }
333  return $parameters;
334  }
335 }
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:153
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:21
‪TYPO3\CMS\Core\Resource\AbstractFile\getForLocalProcessing
‪string getForLocalProcessing($writable=true)
Definition: AbstractFile.php:548
‪TYPO3\CMS\Core\Resource\Processing\TaskInterface
Definition: TaskInterface.php:31
‪TYPO3
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper\getFilenameForImageCropScaleMask
‪string getFilenameForImageCropScaleMask(TaskInterface $task)
Definition: LocalCropScaleMaskHelper.php:298
‪TYPO3\CMS\Core\Utility\MathUtility\forceIntegerInRange
‪static int forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31
‪TYPO3\CMS\Core\Resource\Processing\TaskInterface\getSourceFile
‪Resource File getSourceFile()
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper
Definition: LocalCropScaleMaskHelper.php:27
‪TYPO3\CMS\Core\Resource\Processing
Definition: AbstractGraphicalTask.php:2
‪TYPO3\CMS\Core\Resource\ProcessedFile\getProcessingConfiguration
‪array getProcessingConfiguration()
Definition: ProcessedFile.php:517
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper\getConfigurationForImageCropScaleMask
‪array getConfigurationForImageCropScaleMask(Resource\ProcessedFile $processedFile, \TYPO3\CMS\Frontend\Imaging\GifBuilder $gifBuilder)
Definition: LocalCropScaleMaskHelper.php:266
‪TYPO3\CMS\Core\Resource\ProcessedFile\generateProcessedFileNameWithoutExtension
‪string generateProcessedFileNameWithoutExtension()
Definition: ProcessedFile.php:552
‪TYPO3\CMS\Core\Resource\Processing\LocalImageProcessor
Definition: LocalImageProcessor.php:24
‪TYPO3\CMS\Core\Resource\Processing\TaskInterface\getTargetFile
‪Resource ProcessedFile getTargetFile()
‪TYPO3\CMS\Core\Imaging\GraphicalFunctions\getImageScale
‪array getImageScale($info, $w, $h, $options)
Definition: GraphicalFunctions.php:2298
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper\$processor
‪LocalImageProcessor $processor
Definition: LocalCropScaleMaskHelper.php:30
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper\__construct
‪__construct(LocalImageProcessor $processor)
Definition: LocalCropScaleMaskHelper.php:35
‪TYPO3\CMS\Frontend\Imaging\GifBuilder
Definition: GifBuilder.php:52
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper\getNewSvgDimensions
‪array getNewSvgDimensions($file, array $configuration, array $options, GifBuilder $gifBuilder)
Definition: LocalCropScaleMaskHelper.php:232
‪TYPO3\CMS\Core\Resource
Definition: generateMimeTypes.php:37
‪TYPO3\CMS\Core\Resource\ProcessedFile
Definition: ProcessedFile.php:42
‪TYPO3\CMS\Core\Resource\AbstractFile\getExtension
‪string getExtension()
Definition: AbstractFile.php:252
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:39
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:21
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper\process
‪array null process(TaskInterface $task)
Definition: LocalCropScaleMaskHelper.php:59
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper\modifyImageMagickStripProfileParameters
‪string modifyImageMagickStripProfileParameters($parameters, array $configuration)
Definition: LocalCropScaleMaskHelper.php:319
‪TYPO3\CMS\Core\Resource\Processing\TaskInterface\getTargetFileExtension
‪string getTargetFileExtension()