TYPO3 CMS  TYPO3_7-6
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  '',
99  '',
100  '',
101  sprintf('-crop %dx%d+%d+%d', $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']['im'])) {
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 
125  // all other images
126  } else {
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 = $gifBuilder->tempPath . $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']['im_mask_temp_ext_gif']) {
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 
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']['im'] && $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 ($configuration['stripProfile']) {
325  $parameters = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_stripProfileCommand'] . $parameters;
326  } else {
327  $parameters .= '###SkipStripProfile###';
328  }
329  }
330  return $parameters;
331  }
332 }
getNewSvgDimensions($file, array $configuration, array $options, GifBuilder $gifBuilder)
static unlink_tempfile($uploadedTempFileName)
getConfigurationForImageCropScaleMask(Resource\ProcessedFile $processedFile, \TYPO3\CMS\Frontend\Imaging\GifBuilder $gifBuilder)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']