TYPO3 CMS  TYPO3_8-7
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 
20 
25 {
29  protected $processor;
30 
35  {
36  $this->processor = $processor;
37  }
38 
58  public function process(TaskInterface $task)
59  {
60  $result = null;
61  $targetFile = $task->getTargetFile();
62  $sourceFile = $task->getSourceFile();
63 
64  $originalFileName = $sourceFile->getForLocalProcessing(false);
66  $gifBuilder = GeneralUtility::makeInstance(GifBuilder::class);
67  $gifBuilder->init();
68  $gifBuilder->absPrefix = PATH_site;
69 
70  $configuration = $targetFile->getProcessingConfiguration();
71  $configuration['additionalParameters'] = $this->modifyImageMagickStripProfileParameters($configuration['additionalParameters'], $configuration);
72 
73  if (empty($configuration['fileExtension'])) {
74  $configuration['fileExtension'] = $task->getTargetFileExtension();
75  }
76 
77  $options = $this->getConfigurationForImageCropScaleMask($targetFile, $gifBuilder);
78 
79  $croppedImage = null;
80  if (!empty($configuration['crop'])) {
81 
82  // check if it is a json object
83  $cropData = json_decode($configuration['crop']);
84  if ($cropData) {
85  $crop = implode(',', [(int)$cropData->x, (int)$cropData->y, (int)$cropData->width, (int)$cropData->height]);
86  } else {
87  $crop = $configuration['crop'];
88  }
89 
90  list($offsetLeft, $offsetTop, $newWidth, $newHeight) = explode(',', $crop, 4);
91 
92  $backupPrefix = $gifBuilder->filenamePrefix;
93  $gifBuilder->filenamePrefix = 'crop_';
94 
95  // the result info is an array with 0=width,1=height,2=extension,3=filename
96  $result = $gifBuilder->imageMagickConvert(
97  $originalFileName,
98  $configuration['fileExtension'],
99  '',
100  '',
101  sprintf('-crop %dx%d+%d+%d +repage', $newWidth, $newHeight, $offsetLeft, $offsetTop),
102  '',
103  ['noScale' => true],
104  true
105  );
106  $gifBuilder->filenamePrefix = $backupPrefix;
107 
108  if ($result !== null) {
109  $originalFileName = $croppedImage = $result[3];
110  }
111  }
112 
113  // Normal situation (no masking)
114  if (!(is_array($configuration['maskImages']) && $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_enabled'])) {
115 
116  // SVG
117  if ($croppedImage === null && $sourceFile->getExtension() === 'svg') {
118  $newDimensions = $this->getNewSvgDimensions($sourceFile, $configuration, $options, $gifBuilder);
119  $result = [
120  0 => $newDimensions['width'],
121  1 => $newDimensions['height'],
122  3 => '' // no file = use original
123  ];
124  } else {
125  // all other images
126  // the result info is an array with 0=width,1=height,2=extension,3=filename
127  $result = $gifBuilder->imageMagickConvert(
128  $originalFileName,
129  $configuration['fileExtension'],
130  $configuration['width'],
131  $configuration['height'],
132  $configuration['additionalParameters'],
133  $configuration['frame'],
134  $options
135  );
136  }
137  } else {
138  $targetFileName = $this->getFilenameForImageCropScaleMask($task);
139  $temporaryFileName = PATH_site . 'typo3temp/' . $targetFileName;
140  $maskImage = $configuration['maskImages']['maskImage'];
141  $maskBackgroundImage = $configuration['maskImages']['backgroundImage'];
142  if ($maskImage instanceof Resource\FileInterface && $maskBackgroundImage instanceof Resource\FileInterface) {
143  $temporaryExtension = 'png';
144  if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_allowTemporaryMasksAsPng']) {
145  // If ImageMagick version 5+
146  $temporaryExtension = $gifBuilder->gifExtension;
147  }
148  $tempFileInfo = $gifBuilder->imageMagickConvert(
149  $originalFileName,
150  $temporaryExtension,
151  $configuration['width'],
152  $configuration['height'],
153  $configuration['additionalParameters'],
154  $configuration['frame'],
155  $options
156  );
157  if (is_array($tempFileInfo)) {
158  $maskBottomImage = $configuration['maskImages']['maskBottomImage'];
159  if ($maskBottomImage instanceof Resource\FileInterface) {
160  $maskBottomImageMask = $configuration['maskImages']['maskBottomImageMask'];
161  } else {
162  $maskBottomImageMask = null;
163  }
164 
165  // Scaling: ****
166  $tempScale = [];
167  $command = '-geometry ' . $tempFileInfo[0] . 'x' . $tempFileInfo[1] . '!';
168  $command = $this->modifyImageMagickStripProfileParameters($command, $configuration);
169  $tmpStr = $gifBuilder->randomName();
170  // m_mask
171  $tempScale['m_mask'] = $tmpStr . '_mask.' . $temporaryExtension;
172  $gifBuilder->imageMagickExec($maskImage->getForLocalProcessing(true), $tempScale['m_mask'], $command);
173  // m_bgImg
174  $tempScale['m_bgImg'] = $tmpStr . '_bgImg.miff';
175  $gifBuilder->imageMagickExec($maskBackgroundImage->getForLocalProcessing(), $tempScale['m_bgImg'], $command);
176  // m_bottomImg / m_bottomImg_mask
177  if ($maskBottomImage instanceof Resource\FileInterface && $maskBottomImageMask instanceof Resource\FileInterface) {
178  $tempScale['m_bottomImg'] = $tmpStr . '_bottomImg.' . $temporaryExtension;
179  $gifBuilder->imageMagickExec($maskBottomImage->getForLocalProcessing(), $tempScale['m_bottomImg'], $command);
180  $tempScale['m_bottomImg_mask'] = ($tmpStr . '_bottomImg_mask.') . $temporaryExtension;
181  $gifBuilder->imageMagickExec($maskBottomImageMask->getForLocalProcessing(), $tempScale['m_bottomImg_mask'], $command);
182  // BEGIN combining:
183  // The image onto the background
184  $gifBuilder->combineExec($tempScale['m_bgImg'], $tempScale['m_bottomImg'], $tempScale['m_bottomImg_mask'], $tempScale['m_bgImg']);
185  }
186  // The image onto the background
187  $gifBuilder->combineExec($tempScale['m_bgImg'], $tempFileInfo[3], $tempScale['m_mask'], $temporaryFileName);
188  $tempFileInfo[3] = $temporaryFileName;
189  // Unlink the temp-images...
190  foreach ($tempScale as $tempFile) {
191  if (@is_file($tempFile)) {
192  unlink($tempFile);
193  }
194  }
195  }
196  $result = $tempFileInfo;
197  }
198  }
199 
200  // check if the processing really generated a new file (scaled and/or cropped)
201  if ($result !== null) {
202  if ($result[3] !== $originalFileName || $originalFileName === $croppedImage) {
203  $result = [
204  'width' => $result[0],
205  'height' => $result[1],
206  'filePath' => $result[3],
207  ];
208  } else {
209  // No file was generated
210  $result = null;
211  }
212  }
213 
214  // Cleanup temp file if it isn't used as result
215  if ($croppedImage && ($result === null || $croppedImage !== $result['filePath'])) {
216  GeneralUtility::unlink_tempfile($croppedImage);
217  }
218 
219  return $result;
220  }
221 
232  protected function getNewSvgDimensions($file, array $configuration, array $options, GifBuilder $gifBuilder)
233  {
234  $info = [$file->getProperty('width'), $file->getProperty('height')];
235  $data = $gifBuilder->getImageScale($info, $configuration['width'], $configuration['height'], $options);
236 
237  // Turn cropScaling into scaling
238  if ($data['crs']) {
239  if (!$data['origW']) {
240  $data['origW'] = $data[0];
241  }
242  if (!$data['origH']) {
243  $data['origH'] = $data[1];
244  }
245  if ($data[0] > $data['origW']) {
246  $data[1] = (int)(($data['origW'] * $data[1]) / $data[0]);
247  $data[0] = $data['origW'];
248  } else {
249  $data[0] = (int)(($data['origH'] * $data[0]) / $data[1]);
250  $data[1] = $data['origH'];
251  }
252  }
253 
254  return [
255  'width' => $data[0],
256  'height' => $data[1]
257  ];
258  }
259 
266  protected function getConfigurationForImageCropScaleMask(Resource\ProcessedFile $processedFile, \TYPO3\CMS\Frontend\Imaging\GifBuilder $gifBuilder)
267  {
268  $configuration = $processedFile->getProcessingConfiguration();
269 
270  if ($configuration['useSample']) {
271  $gifBuilder->scalecmd = '-sample';
272  }
273  $options = [];
274  if ($configuration['maxWidth']) {
275  $options['maxW'] = $configuration['maxWidth'];
276  }
277  if ($configuration['maxHeight']) {
278  $options['maxH'] = $configuration['maxHeight'];
279  }
280  if ($configuration['minWidth']) {
281  $options['minW'] = $configuration['minWidth'];
282  }
283  if ($configuration['minHeight']) {
284  $options['minH'] = $configuration['minHeight'];
285  }
286 
287  $options['noScale'] = $configuration['noScale'];
288 
289  return $options;
290  }
291 
299  {
300  $configuration = $task->getTargetFile()->getProcessingConfiguration();
301  $targetFileExtension = $task->getSourceFile()->getExtension();
302  $processedFileExtension = $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] ? 'png' : 'gif';
303  if (is_array($configuration['maskImages']) && $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_enabled'] && $task->getSourceFile()->getExtension() != $processedFileExtension) {
304  $targetFileExtension = 'jpg';
305  } elseif ($configuration['fileExtension']) {
306  $targetFileExtension = $configuration['fileExtension'];
307  }
308 
309  return $task->getTargetFile()->generateProcessedFileNameWithoutExtension() . '.' . ltrim(trim($targetFileExtension), '.');
310  }
311 
319  protected function modifyImageMagickStripProfileParameters($parameters, array $configuration)
320  {
321  // Strips profile information of image to save some space:
322  if (isset($configuration['stripProfile'])) {
323  if (
324  $configuration['stripProfile']
325  && $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_stripColorProfileCommand'] !== ''
326  ) {
327  $parameters = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_stripProfileCommand'] . $parameters;
328  } else {
329  $parameters .= '###SkipStripProfile###';
330  }
331  }
332  return $parameters;
333  }
334 }
getNewSvgDimensions($file, array $configuration, array $options, GifBuilder $gifBuilder)
static unlink_tempfile($uploadedTempFileName)
getConfigurationForImageCropScaleMask(Resource\ProcessedFile $processedFile, \TYPO3\CMS\Frontend\Imaging\GifBuilder $gifBuilder)
static makeInstance($className,... $constructorArguments)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']