TYPO3  7.6
PreviewProcessing.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Resource\OnlineMedia\Processing;
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 
29 
34 {
38  protected $processor;
39 
44  protected function needsReprocessing($processedFile)
45  {
46  return $processedFile->isNew()
47  || (!$processedFile->usesOriginalFile() && !$processedFile->exists())
48  || $processedFile->isOutdated();
49  }
50 
62  public function processFile(FileProcessingService $fileProcessingService, AbstractDriver $driver, ProcessedFile $processedFile, File $file, $taskType, array $configuration)
63  {
64  if ($taskType !== 'Image.Preview' && $taskType !== 'Image.CropScaleMask') {
65  return;
66  }
67  // Check if processing is needed
68  if (!$this->needsReprocessing($processedFile)) {
69  return;
70  }
71  // Check if there is a OnlineMediaHelper registered for this file type
72  $helper = OnlineMediaHelperRegistry::getInstance()->getOnlineMediaHelper($file);
73  if ($helper === false) {
74  return;
75  }
76  // Check if helper provides a preview image
77  $temporaryFileName = $helper->getPreviewImage($file);
78  if (empty($temporaryFileName) || !file_exists($temporaryFileName)) {
79  return;
80  }
81  $temporaryFileNameForResizedThumb = uniqid(PATH_site . 'typo3temp/online_media_' . $file->getHashedIdentifier()) . '.jpg';
82  switch ($taskType) {
83  case 'Image.Preview':
84  // Merge custom configuration with default configuration
85  $configuration = array_merge(array('width' => 64, 'height' => 64), $configuration);
86  $configuration['width'] = MathUtility::forceIntegerInRange($configuration['width'], 1, 1000);
87  $configuration['height'] = MathUtility::forceIntegerInRange($configuration['height'], 1, 1000);
88  $this->resizeImage($temporaryFileName, $temporaryFileNameForResizedThumb, $configuration);
89  break;
90 
91  case 'Image.CropScaleMask':
92  $this->cropScaleImage($temporaryFileName, $temporaryFileNameForResizedThumb, $configuration);
93  break;
94  }
95  if (is_file($temporaryFileNameForResizedThumb)) {
96  $processedFile->setName($this->getTargetFileName($processedFile));
97  list($width, $height) = getimagesize($temporaryFileNameForResizedThumb);
98  $processedFile->updateProperties(
99  array(
100  'width' => $width,
101  'height' => $height,
102  'size' => filesize($temporaryFileNameForResizedThumb),
103  'checksum' => $processedFile->getTask()->getConfigurationChecksum()
104  )
105  );
106  $processedFile->updateWithLocalFile($temporaryFileNameForResizedThumb);
107 
109  $processedFileRepository = GeneralUtility::makeInstance(ProcessedFileRepository::class);
110  $processedFileRepository->add($processedFile);
111  }
112  }
113 
119  protected function getTargetFileName(ProcessedFile $processedFile, $prefix = 'preview_')
120  {
121  return $prefix . $processedFile->getTask()->getConfigurationChecksum() . '_' . $processedFile->getOriginalFile()->getNameWithoutExtension() . '.jpg';
122  }
123 
129  protected function resizeImage($originalFileName, $temporaryFileName, $configuration)
130  {
131  // Create the temporary file
132  if (empty($GLOBALS['TYPO3_CONF_VARS']['GFX']['im'])) {
133  return;
134  }
135 
136  if (file_exists($originalFileName)) {
138  'width' => $configuration['width'],
139  'height' => $configuration['height'],
140  'originalFileName' => $originalFileName,
141  'temporaryFileName' => $temporaryFileName,
142  ]);
143  $parameters = '-sample ' . $arguments['width'] . 'x' . $arguments['height'] . ' '
144  . $arguments['originalFileName'] . '[0] ' . $arguments['temporaryFileName'];
145 
146  $cmd = GeneralUtility::imageMagickCommand('convert', $parameters) . ' 2>&1';
147  CommandUtility::exec($cmd);
148  }
149 
150  if (!file_exists($temporaryFileName)) {
151  // Create a error image
152  $graphicalFunctions = $this->getGraphicalFunctionsObject();
153  $graphicalFunctions->getTemporaryImageWithText($temporaryFileName, 'No thumb', 'generated!', basename($originalFileName));
154  }
155  }
156 
164  protected function cropScaleImage($originalFileName, $temporaryFileName, $configuration)
165  {
166  if (file_exists($originalFileName)) {
168  $gifBuilder = GeneralUtility::makeInstance(GifBuilder::class);
169  $gifBuilder->init();
170 
171  $options = $this->getConfigurationForImageCropScaleMask($configuration, $gifBuilder);
172  $info = $gifBuilder->getImageDimensions($originalFileName);
173  $data = $gifBuilder->getImageScale($info, $configuration['width'], $configuration['height'], $options);
174 
175  $info[0] = $data[0];
176  $info[1] = $data[1];
177  $frame = '';
178  $params = $gifBuilder->cmds['jpg'];
179 
180  // Cropscaling:
181  if ($data['crs']) {
182  if (!$data['origW']) {
183  $data['origW'] = $data[0];
184  }
185  if (!$data['origH']) {
186  $data['origH'] = $data[1];
187  }
188  $offsetX = (int)(($data[0] - $data['origW']) * ($data['cropH'] + 100) / 200);
189  $offsetY = (int)(($data[1] - $data['origH']) * ($data['cropV'] + 100) / 200);
190  $params .= ' -crop ' . $data['origW'] . 'x' . $data['origH'] . '+' . $offsetX . '+' . $offsetY . '! ';
191  }
192  $command = $gifBuilder->scalecmd . ' ' . $info[0] . 'x' . $info[1] . '! ' . $params . ' ';
193  $gifBuilder->imageMagickExec($originalFileName, $temporaryFileName, $command, $frame);
194  }
195  if (!file_exists($temporaryFileName)) {
196  // Create a error image
197  $graphicalFunctions = $this->getGraphicalFunctionsObject();
198  $graphicalFunctions->getTemporaryImageWithText($temporaryFileName, 'No thumb', 'generated!', basename($originalFileName));
199  }
200  }
201 
209  protected function getConfigurationForImageCropScaleMask(array $configuration, GifBuilder $gifBuilder)
210  {
211  if (!empty($configuration['useSample'])) {
212  $gifBuilder->scalecmd = '-sample';
213  }
214  $options = array();
215  if (!empty($configuration['maxWidth'])) {
216  $options['maxW'] = $configuration['maxWidth'];
217  }
218  if (!empty($configuration['maxHeight'])) {
219  $options['maxH'] = $configuration['maxHeight'];
220  }
221  if (!empty($configuration['minWidth'])) {
222  $options['minW'] = $configuration['minWidth'];
223  }
224  if (!empty($configuration['minHeight'])) {
225  $options['minH'] = $configuration['minHeight'];
226  }
227 
228  $options['noScale'] = $configuration['noScale'];
229 
230  return $options;
231  }
232 
236  protected function getProcessor()
237  {
238  if (!$this->processor) {
239  $this->processor = GeneralUtility::makeInstance(LocalImageProcessor::class);
240  }
241  return $this->processor;
242  }
243 
247  protected function getGraphicalFunctionsObject()
248  {
249  static $graphicalFunctionsObject = null;
250  if ($graphicalFunctionsObject === null) {
251  $graphicalFunctionsObject = GeneralUtility::makeInstance(GraphicalFunctions::class);
252  }
253  return $graphicalFunctionsObject;
254  }
255 }