‪TYPO3CMS  ‪main
LocalCropScaleMaskHelper.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
23 
28 {
48  public function ‪process(‪TaskInterface $task)
49  {
50  return $this->‪processWithLocalFile($task, $task->‪getSourceFile()->‪getForLocalProcessing(false));
51  }
52 
57  public function ‪processWithLocalFile(‪TaskInterface $task, string $originalFileName): ?array
58  {
59  $result = null;
60  $targetFile = $task->‪getTargetFile();
61 
62  $imageOperations = GeneralUtility::makeInstance(GraphicalFunctions::class);
63 
64  $configuration = $targetFile->getProcessingConfiguration();
65  $configuration['additionalParameters'] = $this->‪modifyImageMagickStripProfileParameters((string)($configuration['additionalParameters'] ?? ''), $configuration);
66 
67  if (empty($configuration['fileExtension'])) {
68  $configuration['fileExtension'] = $task->‪getTargetFileExtension();
69  }
70 
71  $options = $this->‪getConfigurationForImageCropScaleMask($targetFile);
72 
73  $croppedImage = null;
74  if (!empty($configuration['crop'])) {
75  // the result info is an array with 0=width,1=height,2=extension,3=filename
76  $result = $imageOperations->crop($originalFileName, $configuration['fileExtension'], $configuration['crop']);
77  if ($result !== null) {
78  $originalFileName = $croppedImage = $result[3];
79  }
80  }
81 
82  // Normal situation (no masking)
83  if (!(is_array($configuration['maskImages'] ?? null) && ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_enabled'])) {
84  // the result info is an array with 0=width,1=height,2=extension,3=filename
85  $result = $imageOperations->imageMagickConvert(
86  $originalFileName,
87  $configuration['fileExtension'],
88  $configuration['width'] ?? '',
89  $configuration['height'] ?? '',
90  $configuration['additionalParameters'],
91  $configuration['frame'] ?? '',
92  $options,
93  // in case file is in `/typo3temp/` from the crop operation above, it must create a result
94  $result !== null
95  );
96  } else {
97  $targetFileName = $this->‪getFilenameForImageCropScaleMask($task);
98  $temporaryFileName = ‪Environment::getPublicPath() . '/typo3temp/' . $targetFileName;
99  $maskImage = $configuration['maskImages']['maskImage'] ?? null;
100  $maskBackgroundImage = $configuration['maskImages']['backgroundImage'];
101  if ($maskImage instanceof ‪FileInterface && $maskBackgroundImage instanceof ‪FileInterface) {
102  // This converts the original image to a temporary PNG file during all steps of the masking process
103  $tempFileInfo = $imageOperations->imageMagickConvert(
104  $originalFileName,
105  'png',
106  $configuration['width'] ?? '',
107  $configuration['height'] ?? '',
108  $configuration['additionalParameters'],
109  $configuration['frame'] ?? '',
110  $options
111  );
112  if (is_array($tempFileInfo)) {
113  // Scaling
114  $command = '-geometry ' . $tempFileInfo[0] . 'x' . $tempFileInfo[1] . '!';
115  $command = $this->‪modifyImageMagickStripProfileParameters($command, $configuration);
116 
117  $imageOperations->mask(
118  $tempFileInfo[3],
119  $temporaryFileName,
120  $maskImage->getForLocalProcessing(),
121  $maskBackgroundImage->getForLocalProcessing(),
122  $command
123  );
124  $maskBottomImage = $configuration['maskImages']['maskBottomImage'] ?? null;
125  $maskBottomImageMask = $configuration['maskImages']['maskBottomImageMask'] ?? null;
126  if ($maskBottomImage instanceof ‪FileInterface && $maskBottomImageMask instanceof ‪FileInterface) {
127  // Uses the temporary PNG file from the previous step and applies another mask
128  $imageOperations->mask(
129  $temporaryFileName,
130  $temporaryFileName,
131  $maskBottomImage->getForLocalProcessing(),
132  $maskBottomImageMask->getForLocalProcessing(),
133  $command
134  );
135  }
136  $tempFileInfo[3] = $temporaryFileName;
137  }
138  $result = $tempFileInfo;
139  }
140  }
141 
142  // check if the processing really generated a new file (scaled and/or cropped)
143  if ($result !== null) {
144  if ($result[3] !== $originalFileName || $originalFileName === $croppedImage) {
145  $result = [
146  'width' => $result[0],
147  'height' => $result[1],
148  'filePath' => $result[3],
149  ];
150  } else {
151  // No file was generated
152  $result = null;
153  }
154  }
155 
156  // Cleanup temp file if it isn't used as result
157  if ($croppedImage && ($result === null || $croppedImage !== $result['filePath'])) {
158  GeneralUtility::unlink_tempfile($croppedImage);
159  }
160 
161  // If noScale option is applied, we need to reset the width and height to ensure the scaled values
162  // are used for the generated image tag even if the image itself is not scaled. This is needed, as
163  // the result is discarded due to the fact that the original image is used.
164  // @see https://forge.typo3.org/issues/100972
165  // Note: This should only happen if no image has been generated ($result === null).
166  if ($result === null && ($options['noScale'] ?? false)) {
167  $configuration = $task->‪getConfiguration();
168  $localProcessedFile = $task->‪getSourceFile()->‪getForLocalProcessing(false);
169  $imageDimensions = $imageOperations->getImageDimensions($localProcessedFile);
170  $imageScaleInfo = $imageOperations->getImageScale(
171  $imageDimensions,
172  $configuration['width'] ?? '',
173  $configuration['height'] ?? '',
174  $options
175  );
176  $targetFile->updateProperties([
177  'width' => $imageScaleInfo[0],
178  'height' => $imageScaleInfo[1],
179  ]);
180  }
181 
182  return $result;
183  }
184 
185  protected function ‪getConfigurationForImageCropScaleMask(‪ProcessedFile $processedFile): array
186  {
187  $configuration = $processedFile->‪getProcessingConfiguration();
188 
189  $options = [];
190  if ($configuration['sample'] ?? false) {
191  $options['sample'] = true;
192  }
193  if ($configuration['maxWidth'] ?? false) {
194  $options['maxW'] = $configuration['maxWidth'];
195  }
196  if ($configuration['maxHeight'] ?? false) {
197  $options['maxH'] = $configuration['maxHeight'];
198  }
199  if ($configuration['minWidth'] ?? false) {
200  $options['minW'] = $configuration['minWidth'];
201  }
202  if ($configuration['minHeight'] ?? false) {
203  $options['minH'] = $configuration['minHeight'];
204  }
205 
206  $options['noScale'] = $configuration['noScale'] ?? null;
207 
208  return $options;
209  }
210 
217  {
218  $configuration = $task->‪getTargetFile()->‪getProcessingConfiguration();
219  $targetFileExtension = $configuration['fileExtension'] ?? $task->‪getSourceFile()->‪getExtension();
220  return $task->‪getTargetFile()->‪generateProcessedFileNameWithoutExtension() . '.' . ltrim(trim($targetFileExtension), '.');
221  }
222 
230  protected function ‪modifyImageMagickStripProfileParameters(string $parameters, array $configuration)
231  {
232  // Strips profile information of image to save some space:
233  if (isset($configuration['stripProfile'])) {
234  if (
235  $configuration['stripProfile']
236  && ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_stripColorProfileCommand'] !== ''
237  ) {
238  $parameters = ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_stripColorProfileCommand'] . $parameters;
239  } else {
240  $parameters .= '###SkipStripProfile###';
241  }
242  }
243  return $parameters;
244  }
245 }
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper\processWithLocalFile
‪processWithLocalFile(TaskInterface $task, string $originalFileName)
Definition: LocalCropScaleMaskHelper.php:57
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper\modifyImageMagickStripProfileParameters
‪string modifyImageMagickStripProfileParameters(string $parameters, array $configuration)
Definition: LocalCropScaleMaskHelper.php:230
‪TYPO3\CMS\Core\Resource\AbstractFile\getForLocalProcessing
‪non empty string getForLocalProcessing(bool $writable=true)
Definition: AbstractFile.php:551
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:24
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper\getConfigurationForImageCropScaleMask
‪getConfigurationForImageCropScaleMask(ProcessedFile $processedFile)
Definition: LocalCropScaleMaskHelper.php:185
‪TYPO3\CMS\Core\Resource\Processing\TaskInterface
Definition: TaskInterface.php:33
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static getPublicPath()
Definition: Environment.php:187
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper\getFilenameForImageCropScaleMask
‪string getFilenameForImageCropScaleMask(TaskInterface $task)
Definition: LocalCropScaleMaskHelper.php:216
‪TYPO3\CMS\Core\Resource\Processing\TaskInterface\getSourceFile
‪Resource File getSourceFile()
‪TYPO3\CMS\Core\Resource\AbstractFile\getExtension
‪getExtension()
Definition: AbstractFile.php:236
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper
Definition: LocalCropScaleMaskHelper.php:28
‪TYPO3\CMS\Core\Resource\Processing
Definition: AbstractGraphicalTask.php:16
‪TYPO3\CMS\Core\Resource\ProcessedFile\getProcessingConfiguration
‪array getProcessingConfiguration()
Definition: ProcessedFile.php:532
‪TYPO3\CMS\Core\Resource\ProcessedFile\generateProcessedFileNameWithoutExtension
‪string generateProcessedFileNameWithoutExtension()
Definition: ProcessedFile.php:566
‪TYPO3\CMS\Core\Imaging\GraphicalFunctions
Definition: GraphicalFunctions.php:33
‪TYPO3\CMS\Core\Resource\Processing\TaskInterface\getTargetFile
‪Resource ProcessedFile getTargetFile()
‪TYPO3\CMS\Core\Resource\Processing\TaskInterface\getConfiguration
‪array getConfiguration()
‪TYPO3\CMS\Core\Resource\ProcessedFile
Definition: ProcessedFile.php:47
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper\process
‪array null process(TaskInterface $task)
Definition: LocalCropScaleMaskHelper.php:48
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Core\Resource\Processing\TaskInterface\getTargetFileExtension
‪string getTargetFileExtension()