/** * This method actually does the processing of files locally * * takes the original file (on remote storages this will be fetched from the remote server) * does the IM magic on the local server by creating a temporary typo3temp/ file * copies the typo3temp/ file to the processing folder of the target storage * removes the typo3temp/ file * * @param TaskInterface $task * @return array */ public function process(TaskInterface $task) { $targetFile = $task->getTargetFile(); $sourceFile = $task->getSourceFile(); // Merge custom configuration with default configuration $configuration = array_merge(array('width' => 64, 'height' => 64), $task->getConfiguration()); $configuration['width'] = Utility\MathUtility::forceIntegerInRange($configuration['width'], 1); $configuration['height'] = Utility\MathUtility::forceIntegerInRange($configuration['height'], 1); $originalFileName = $sourceFile->getForLocalProcessing(FALSE); // Create a temporaryFile $temporaryFileName = Utility\GeneralUtility::tempnam('preview_', '.' . $task->getTargetFileExtension()); // Check file extension if ($sourceFile->getType() != Resource\File::FILETYPE_IMAGE && !Utility\GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $sourceFile->getExtension())) { // Create a default image $this->processor->getTemporaryImageWithText($temporaryFileName, 'Not imagefile!', 'No ext!', $sourceFile->getName()); } else { // Create the temporary file if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) { $parameters = '-sample ' . $configuration['width'] . 'x' . $configuration['height'] . ' ' . $this->processor->wrapFileName($originalFileName) . '[0] ' . $this->processor->wrapFileName($temporaryFileName); $cmd = Utility\GeneralUtility::imageMagickCommand('convert', $parameters) . ' 2>&1'; Utility\CommandUtility::exec($cmd); if (!file_exists($temporaryFileName)) { // Create a error gif $this->processor->getTemporaryImageWithText($temporaryFileName, 'No thumb', 'generated!', $sourceFile->getName()); } } } return array('filePath' => $temporaryFileName); }
/** * This method actually does the processing of files locally * * Takes the original file (for remote storages this will be fetched from the remote server), * does the IM magic on the local server by creating a temporary typo3temp/ file, * copies the typo3temp/ file to the processing folder of the target storage and * removes the typo3temp/ file. * * The returned array has the following structure: * width => 100 * height => 200 * filePath => /some/path * * If filePath isn't set but width and height are the original file is used as ProcessedFile * with the returned width and height. This is for example useful for SVG images. * * @param TaskInterface $task * @return array|NULL */ public function process(TaskInterface $task) { $result = null; $targetFile = $task->getTargetFile(); $sourceFile = $task->getSourceFile(); $originalFileName = $sourceFile->getForLocalProcessing(false); /** @var $gifBuilder GifBuilder */ $gifBuilder = GeneralUtility::makeInstance(GifBuilder::class); $gifBuilder->init(); $gifBuilder->absPrefix = PATH_site; $configuration = $targetFile->getProcessingConfiguration(); $configuration['additionalParameters'] = $this->modifyImageMagickStripProfileParameters($configuration['additionalParameters'], $configuration); if (empty($configuration['fileExtension'])) { $configuration['fileExtension'] = $task->getTargetFileExtension(); } $options = $this->getConfigurationForImageCropScaleMask($targetFile, $gifBuilder); $croppedImage = null; if (!empty($configuration['crop'])) { // check if it is a json object $cropData = json_decode($configuration['crop']); if ($cropData) { $crop = implode(',', array((int) $cropData->x, (int) $cropData->y, (int) $cropData->width, (int) $cropData->height)); } else { $crop = $configuration['crop']; } list($offsetLeft, $offsetTop, $newWidth, $newHeight) = explode(',', $crop, 4); $backupPrefix = $gifBuilder->filenamePrefix; $gifBuilder->filenamePrefix = 'crop_'; // the result info is an array with 0=width,1=height,2=extension,3=filename $result = $gifBuilder->imageMagickConvert($originalFileName, '', '', '', sprintf('-crop %dx%d+%d+%d', $newWidth, $newHeight, $offsetLeft, $offsetTop), '', ['noScale' => true], true); $gifBuilder->filenamePrefix = $backupPrefix; if ($result !== null) { $originalFileName = $croppedImage = $result[3]; } } // Normal situation (no masking) if (!(is_array($configuration['maskImages']) && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im'])) { // SVG if ($croppedImage === null && $sourceFile->getExtension() === 'svg') { $newDimensions = $this->getNewSvgDimensions($sourceFile, $configuration, $options, $gifBuilder); $result = array(0 => $newDimensions['width'], 1 => $newDimensions['height'], 3 => ''); // all other images } else { // the result info is an array with 0=width,1=height,2=extension,3=filename $result = $gifBuilder->imageMagickConvert($originalFileName, $configuration['fileExtension'], $configuration['width'], $configuration['height'], $configuration['additionalParameters'], $configuration['frame'], $options); } } else { $targetFileName = $this->getFilenameForImageCropScaleMask($task); $temporaryFileName = $gifBuilder->tempPath . $targetFileName; $maskImage = $configuration['maskImages']['maskImage']; $maskBackgroundImage = $configuration['maskImages']['backgroundImage']; if ($maskImage instanceof Resource\FileInterface && $maskBackgroundImage instanceof Resource\FileInterface) { $temporaryExtension = 'png'; if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_mask_temp_ext_gif']) { // If ImageMagick version 5+ $temporaryExtension = $gifBuilder->gifExtension; } $tempFileInfo = $gifBuilder->imageMagickConvert($originalFileName, $temporaryExtension, $configuration['width'], $configuration['height'], $configuration['additionalParameters'], $configuration['frame'], $options); if (is_array($tempFileInfo)) { $maskBottomImage = $configuration['maskImages']['maskBottomImage']; if ($maskBottomImage instanceof Resource\FileInterface) { $maskBottomImageMask = $configuration['maskImages']['maskBottomImageMask']; } else { $maskBottomImageMask = null; } // Scaling: **** $tempScale = array(); $command = '-geometry ' . $tempFileInfo[0] . 'x' . $tempFileInfo[1] . '!'; $command = $this->modifyImageMagickStripProfileParameters($command, $configuration); $tmpStr = $gifBuilder->randomName(); // m_mask $tempScale['m_mask'] = $tmpStr . '_mask.' . $temporaryExtension; $gifBuilder->imageMagickExec($maskImage->getForLocalProcessing(true), $tempScale['m_mask'], $command); // m_bgImg $tempScale['m_bgImg'] = $tmpStr . '_bgImg.miff'; $gifBuilder->imageMagickExec($maskBackgroundImage->getForLocalProcessing(), $tempScale['m_bgImg'], $command); // m_bottomImg / m_bottomImg_mask if ($maskBottomImage instanceof Resource\FileInterface && $maskBottomImageMask instanceof Resource\FileInterface) { $tempScale['m_bottomImg'] = $tmpStr . '_bottomImg.' . $temporaryExtension; $gifBuilder->imageMagickExec($maskBottomImage->getForLocalProcessing(), $tempScale['m_bottomImg'], $command); $tempScale['m_bottomImg_mask'] = $tmpStr . '_bottomImg_mask.' . $temporaryExtension; $gifBuilder->imageMagickExec($maskBottomImageMask->getForLocalProcessing(), $tempScale['m_bottomImg_mask'], $command); // BEGIN combining: // The image onto the background $gifBuilder->combineExec($tempScale['m_bgImg'], $tempScale['m_bottomImg'], $tempScale['m_bottomImg_mask'], $tempScale['m_bgImg']); } // The image onto the background $gifBuilder->combineExec($tempScale['m_bgImg'], $tempFileInfo[3], $tempScale['m_mask'], $temporaryFileName); $tempFileInfo[3] = $temporaryFileName; // Unlink the temp-images... foreach ($tempScale as $tempFile) { if (@is_file($tempFile)) { unlink($tempFile); } } } $result = $tempFileInfo; } } // check if the processing really generated a new file (scaled and/or cropped) if ($result !== null) { if ($result[3] !== $originalFileName || $originalFileName === $croppedImage) { $result = array('width' => $result[0], 'height' => $result[1], 'filePath' => $result[3]); } else { // No file was generated $result = null; } } // Cleanup temp file if it isn't used as result if ($croppedImage && ($result === null || $croppedImage !== $result['filePath'])) { GeneralUtility::unlink_tempfile($croppedImage); } return $result; }
/** * This method actually does the processing of files locally * * Takes the original file (for remote storages this will be fetched from the remote server), * does the IM magic on the local server by creating a temporary typo3temp/ file, * copies the typo3temp/ file to the processing folder of the target storage and * removes the typo3temp/ file. * * The returned array has the following structure: * width => 100 * height => 200 * filePath => /some/path * * @param TaskInterface $task * @return array|NULL */ public function process(TaskInterface $task) { $result = NULL; $targetFile = $task->getTargetFile(); $sourceFile = $task->getSourceFile(); $originalFileName = $sourceFile->getForLocalProcessing(FALSE); /** @var $gifBuilder \TYPO3\CMS\Frontend\Imaging\GifBuilder */ $gifBuilder = Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Imaging\\GifBuilder'); $gifBuilder->init(); $gifBuilder->absPrefix = PATH_site; $configuration = $targetFile->getProcessingConfiguration(); $configuration['additionalParameters'] = $this->modifyImageMagickStripProfileParameters($configuration['additionalParameters'], $configuration); if (empty($configuration['fileExtension'])) { $configuration['fileExtension'] = $task->getTargetFileExtension(); } $options = $this->getConfigurationForImageCropScaleMask($targetFile, $gifBuilder); // Normal situation (no masking) if (!(is_array($configuration['maskImages']) && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im'])) { // the result info is an array with 0=width,1=height,2=extension,3=filename $result = $gifBuilder->imageMagickConvert($originalFileName, $configuration['fileExtension'], $configuration['width'], $configuration['height'], $configuration['additionalParameters'], $configuration['frame'], $options); } else { $targetFileName = $this->getFilenameForImageCropScaleMask($task); $temporaryFileName = $gifBuilder->tempPath . $targetFileName; $maskImage = $configuration['maskImages']['maskImage']; $maskBackgroundImage = $configuration['maskImages']['backgroundImage']; if ($maskImage instanceof Resource\FileInterface && $maskBackgroundImage instanceof Resource\FileInterface) { $temporaryExtension = 'png'; if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_mask_temp_ext_gif']) { // If ImageMagick version 5+ $temporaryExtension = $gifBuilder->gifExtension; } $tempFileInfo = $gifBuilder->imageMagickConvert($originalFileName, $temporaryExtension, $configuration['width'], $configuration['height'], $configuration['additionalParameters'], $configuration['frame'], $options); if (is_array($tempFileInfo)) { $maskBottomImage = $configuration['maskImages']['maskBottomImage']; if ($maskBottomImage instanceof Resource\FileInterface) { $maskBottomImageMask = $configuration['maskImages']['maskBottomImageMask']; } else { $maskBottomImageMask = NULL; } // Scaling: **** $tempScale = array(); $command = '-geometry ' . $tempFileInfo[0] . 'x' . $tempFileInfo[1] . '!'; $command = $this->modifyImageMagickStripProfileParameters($command, $configuration); $tmpStr = $gifBuilder->randomName(); // m_mask $tempScale['m_mask'] = $tmpStr . '_mask.' . $temporaryExtension; $gifBuilder->imageMagickExec($maskImage->getForLocalProcessing(TRUE), $tempScale['m_mask'], $command); // m_bgImg $tempScale['m_bgImg'] = $tmpStr . '_bgImg.miff'; $gifBuilder->imageMagickExec($maskBackgroundImage->getForLocalProcessing(), $tempScale['m_bgImg'], $command); // m_bottomImg / m_bottomImg_mask if ($maskBottomImage instanceof Resource\FileInterface && $maskBottomImageMask instanceof Resource\FileInterface) { $tempScale['m_bottomImg'] = $tmpStr . '_bottomImg.' . $temporaryExtension; $gifBuilder->imageMagickExec($maskBottomImage->getForLocalProcessing(), $tempScale['m_bottomImg'], $command); $tempScale['m_bottomImg_mask'] = $tmpStr . '_bottomImg_mask.' . $temporaryExtension; $gifBuilder->imageMagickExec($maskBottomImageMask->getForLocalProcessing(), $tempScale['m_bottomImg_mask'], $command); // BEGIN combining: // The image onto the background $gifBuilder->combineExec($tempScale['m_bgImg'], $tempScale['m_bottomImg'], $tempScale['m_bottomImg_mask'], $tempScale['m_bgImg']); } // The image onto the background $gifBuilder->combineExec($tempScale['m_bgImg'], $tempFileInfo[3], $tempScale['m_mask'], $temporaryFileName); $tempFileInfo[3] = $temporaryFileName; // Unlink the temp-images... foreach ($tempScale as $tempFile) { if (@is_file($tempFile)) { unlink($tempFile); } } } $result = $tempFileInfo; } } // check if the processing really generated a new file if ($result !== NULL) { if ($result[3] !== $originalFileName) { $result = array('width' => $result[0], 'height' => $result[1], 'filePath' => $result[3]); } else { // No file was generated $result = NULL; } } return $result; }
/** * Returns the path to a temporary file for processing * * @param TaskInterface $task * @return string */ protected function getTemporaryFilePath(TaskInterface $task) { return GeneralUtility::tempnam('preview_', '.' . $task->getTargetFileExtension()); }