Classes/Service/ImageResizer.php
public function processFile($fileName, $targetFileName = '', $targetDirectory = '', \TYPO3\CMS\Core\Resource\File $file = null, \TYPO3\CMS\Core\Authentication\BackendUserAuthentication $backendUser = null, $callbackNotification = null)
    {
        $this->lastMetadata = null;

        if (!(empty($targetFileName) && empty($targetDirectory))) {
            $targetDirectory = rtrim($targetDirectory, '/') . '/';
            $ruleset = $this->getRuleset($fileName, $targetDirectory . $targetFileName, $backendUser);
        } else {
            $ruleset = $this->getRuleset($fileName, $fileName, $backendUser);
        }

        if (count($ruleset) === 0) {
            // File does not match any rule set
            return $fileName;
        }

        // Make file name relative, store as $targetFileName
        if (empty($targetFileName)) {
            $targetFileName = PathUtility::stripPathSitePrefix($fileName);
        }

        // Extract the extension
        if (($dotPosition = strrpos($fileName, '.')) === false) {
            // File has no extension
            return $fileName;
        }
        $fileExtension = strtolower(substr($fileName, $dotPosition + 1));

        if ($fileExtension === 'png' && !$ruleset['resize_png_with_alpha']) {
            if (ImageUtility::isTransparentPng($fileName)) {
                $message = sprintf(
                    $this->localize('LLL:EXT:image_autoresize/Resources/Private/Language/locallang.xlf:message.imageTransparent'),
                    $targetFileName
                );
                $this->notify($callbackNotification, $message, \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING);
                return $fileName;
            }
        }
        if ($fileExtension === 'gif' && ImageUtility::isAnimatedGif($fileName)) {
            $message = sprintf(
                $this->localize('LLL:EXT:image_autoresize/Resources/Private/Language/locallang.xlf:message.imageAnimated'),
                $targetFileName
            );
            $this->notify($callbackNotification, $message, \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING);
            return $fileName;
        }

        $processedFileName = $this->getProcessedFileName($fileName, $backendUser, $ruleset);
        if ($processedFileName === null) {
            // No processing to do
            return $fileName;
        }

        if (!is_writable($fileName)) {
            $message = sprintf(
                $this->localize('LLL:EXT:image_autoresize/Resources/Private/Language/locallang.xlf:message.imageNotWritable'),
                $targetFileName
            );
            $this->notify($callbackNotification, $message, \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
            return $fileName;
        }

        $targetDestFileName = $fileName;
        if (isset($ruleset['conversion_mapping'][$fileExtension])) {
            // File format will be converted
            $destExtension = $ruleset['conversion_mapping'][$fileExtension];
            $destDirectory = PathUtility::dirname($fileName);
            $destFileName = PathUtility::basename(substr($fileName, 0, strlen($fileName) - strlen($fileExtension)) . $destExtension);

            if (empty($targetDirectory)) {
                // Ensures $destFileName does not yet exist, otherwise make it unique!
                /* @var $fileFunc \TYPO3\CMS\Core\Utility\File\BasicFileUtility */
                $fileFunc = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Utility\File\BasicFileUtility::class);
                $destFileName = $fileFunc->getUniqueName($destFileName, $destDirectory);
                $targetDestFileName = $destFileName;
            } else {
                $destFileName = $destDirectory . '/' . $destFileName;
                $targetDestFileName = $targetDirectory . PathUtility::basename(substr($targetFileName, 0, strlen($targetFileName) - strlen($fileExtension)) . $destExtension);
            }
        } else {
            // File format stays the same
            $destExtension = $fileExtension;
            $destFileName = $fileName;
        }

        // Image is bigger than allowed, will now resize it to (hopefully) make it lighter
        /** @var $gifCreator \TYPO3\CMS\Frontend\Imaging\GifBuilder */
        $gifCreator = GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Imaging\GifBuilder::class);
        $gifCreator->init();
        $gifCreator->absPrefix = PATH_site;

        $imParams = isset($gifCreator->cmds[$destExtension]) ? $gifCreator->cmds[$destExtension] : '';
        $imParams .= (bool)$ruleset['keep_metadata'] === true ? ' ###SkipStripProfile###' : '';
        $metadata = ImageUtility::getMetadata($fileName, true);
        $this->lastMetadata = $metadata;
        $isRotated = false;

        if ((bool)$ruleset['auto_orient'] === true) {
            $orientation = ImageUtility::getOrientation($fileName);
            $isRotated = ImageUtility::isRotated($orientation);
            $transformation = ImageUtility::getTransformation($orientation);
            if ($transformation !== '') {
                $imParams .= ' ' . $transformation;
            }
        }

        if (
            isset($ruleset['max_size'])
            && $ruleset['max_size'] > 0
            && isset($metadata['width'])
            && $metadata['width'] > 0
            && isset($metadata['height'])
            && $metadata['height'] > 0
            && $metadata['width'] * $metadata['height'] > $ruleset['max_size']
        ) {
            $factor = sqrt($ruleset['max_size'] / ($metadata['width'] * $metadata['height']));

            $ruleset['max_width'] = min($ruleset['max_width'], floor($metadata['width'] * $factor));
            $ruleset['max_height'] = min($ruleset['max_height'], floor($metadata['height'] * $factor));
        }

        if ($isRotated) {
            // Invert max_width and max_height as the picture
            // will be automatically rotated
            $options = [
                'maxW' => $ruleset['max_height'],
                'maxH' => $ruleset['max_width'],
            ];
        } else {
            $options = [
                'maxW' => $ruleset['max_width'],
                'maxH' => $ruleset['max_height'],
            ];
        }

        $originalFileSize = filesize($fileName);
        $tempFileInfo = null;
        $tempFileInfo = $gifCreator->imageMagickConvert($fileName, $destExtension, '', '', $imParams, '', $options, true);
        if (filesize($tempFileInfo[3]) >= $originalFileSize - 10240 && $destExtension === $fileExtension) {
            // Conversion leads to same or bigger file (rounded to 10KB to accomodate tiny variations in compression) => skip!
            $tempFileInfo = null;
        }
        if ($tempFileInfo) {
            // Signal to post-process the image
            $this->signalSlotDispatcher->dispatch(
                __CLASS__,
                'afterImageResize',
                [
                    'operation' => ($fileName === $destFileName) ? 'RESIZE' : 'RESIZE_CONVERT',
                    'source' => $fileName,
                    'destination' => $tempFileInfo[3],
                    'newWidth' => &$tempFileInfo[0],
                    'newHeight' => &$tempFileInfo[1],
                ]
            );

            $newFileSize = filesize($tempFileInfo[3]);
            $this->reportAdditionalStorageClaimed($originalFileSize - $newFileSize);

            // Replace original file
            @unlink($fileName);
            @rename($tempFileInfo[3], $destFileName);

            if ($fileName === $destFileName) {
                $message = sprintf(
                    $this->localize('LLL:EXT:image_autoresize/Resources/Private/Language/locallang.xlf:message.imageResized'),
                    $targetFileName, $tempFileInfo[0], $tempFileInfo[1]
                );
            } else {
                $message = sprintf(
                    $this->localize('LLL:EXT:image_autoresize/Resources/Private/Language/locallang.xlf:message.imageResizedAndRenamed'),
                    $targetFileName, $tempFileInfo[0], $tempFileInfo[1], PathUtility::basename($targetDestFileName)
                );
            }

            // Indexation in TYPO3 6.2 is using another signal, after the file
            // has been actually uploaded
            $this->lastMetadata['COMPUTED']['Width'] = $tempFileInfo[0];
            $this->lastMetadata['COMPUTED']['Height'] = $tempFileInfo[1];

            if ($isRotated && (bool)$ruleset['keep_metadata'] === true && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] === 'gm') {
                ImageUtility::resetOrientation($destFileName);
            }

            // Inform FAL about new image size and dimensions
            try {
                $destinationFile = ResourceFactory::getInstance()->retrieveFileOrFolderObject($destFileName);
                if ($destinationFile instanceof File) {
                    $indexer = $this->getIndexer($destinationFile->getStorage());
                    $indexer->updateIndexEntry($destinationFile);
                }
            } catch (FolderDoesNotExistException $e) {
                // We are in upload process. Do nothing
            }

            $this->notify($callbackNotification, $message, \TYPO3\CMS\Core\Messaging\FlashMessage::INFO);
        } else {
            // Destination file was not written
            $destFileName = $fileName;
        }
        return $destFileName;
    }
public function processFile($fileName, $targetFileName = '', $targetDirectory = '', \TYPO3\CMS\Core\Resource\File $file = null, \TYPO3\CMS\Core\Authentication\BackendUserAuthentication $backendUser = null, $callbackNotification = null)
    {
        $this->lastMetadata = null;

        if (!(empty($targetFileName) && empty($targetDirectory))) {
            $targetDirectory = rtrim($targetDirectory, '/') . '/';
            $ruleset = $this->getRuleset($fileName, $targetDirectory . $targetFileName, $backendUser);
        } else {
            $ruleset = $this->getRuleset($fileName, $fileName, $backendUser);
        }

        if (count($ruleset) === 0) {
            // File does not match any rule set
            return $fileName;
        }

        // Make file name relative, store as $targetFileName
        if (empty($targetFileName)) {
            $targetFileName = PathUtility::stripPathSitePrefix($fileName);
        }

        // Extract the extension
        if (($dotPosition = strrpos($fileName, '.')) === false) {
            // File has no extension
            return $fileName;
        }
        $fileExtension = strtolower(substr($fileName, $dotPosition + 1));

        if ($fileExtension === 'png' && !$ruleset['resize_png_with_alpha']) {
            if (ImageUtility::isTransparentPng($fileName)) {
                $message = sprintf(
                    $this->localize('LLL:EXT:image_autoresize/Resources/Private/Language/locallang.xlf:message.imageTransparent'),
                    $targetFileName
                );
                $this->notify($callbackNotification, $message, \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING);
                return $fileName;
            }
        }
        if ($fileExtension === 'gif' && ImageUtility::isAnimatedGif($fileName)) {
            $message = sprintf(
                $this->localize('LLL:EXT:image_autoresize/Resources/Private/Language/locallang.xlf:message.imageAnimated'),
                $targetFileName
            );
            $this->notify($callbackNotification, $message, \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING);
            return $fileName;
        }

        $processedFileName = $this->getProcessedFileName($fileName, $backendUser, $ruleset);
        if ($processedFileName === null) {
            // No processing to do
            return $fileName;
        }

        if (!is_writable($fileName)) {
            $message = sprintf(
                $this->localize('LLL:EXT:image_autoresize/Resources/Private/Language/locallang.xlf:message.imageNotWritable'),
                $targetFileName
            );
            $this->notify($callbackNotification, $message, \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
            return $fileName;
        }

        $targetDestFileName = $fileName;
        if (isset($ruleset['conversion_mapping'][$fileExtension])) {
            // File format will be converted
            $destExtension = $ruleset['conversion_mapping'][$fileExtension];
            $destDirectory = PathUtility::dirname($fileName);
            $destFileName = PathUtility::basename(substr($fileName, 0, strlen($fileName) - strlen($fileExtension)) . $destExtension);

            if (empty($targetDirectory)) {
                // Ensures $destFileName does not yet exist, otherwise make it unique!
                /* @var $fileFunc \TYPO3\CMS\Core\Utility\File\BasicFileUtility */
                $fileFunc = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Utility\File\BasicFileUtility::class);
                $destFileName = $fileFunc->getUniqueName($destFileName, $destDirectory);
                $targetDestFileName = $destFileName;
            } else {
                $destFileName = $destDirectory . '/' . $destFileName;
                $targetDestFileName = $targetDirectory . PathUtility::basename(substr($targetFileName, 0, strlen($targetFileName) - strlen($fileExtension)) . $destExtension);
            }
        } else {
            // File format stays the same
            $destExtension = $fileExtension;
            $destFileName = $fileName;
        }

        // Image is bigger than allowed, will now resize it to (hopefully) make it lighter
        /** @var $gifCreator \TYPO3\CMS\Frontend\Imaging\GifBuilder */
        $gifCreator = GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Imaging\GifBuilder::class);
        $gifCreator->init();
        $gifCreator->absPrefix = PATH_site;

        $imParams = isset($gifCreator->cmds[$destExtension]) ? $gifCreator->cmds[$destExtension] : '';
        $imParams .= (bool)$ruleset['keep_metadata'] === true ? ' ###SkipStripProfile###' : '';
        $metadata = ImageUtility::getMetadata($fileName, true);
        $this->lastMetadata = $metadata;
        $isRotated = false;

        if ((bool)$ruleset['auto_orient'] === true) {
            $orientation = ImageUtility::getOrientation($fileName);
            $isRotated = ImageUtility::isRotated($orientation);
            $transformation = ImageUtility::getTransformation($orientation);
            if ($transformation !== '') {
                $imParams .= ' ' . $transformation;
            }
        }

        if (
            isset($ruleset['max_size'])
            && $ruleset['max_size'] > 0
            && isset($metadata['width'])
            && $metadata['width'] > 0
            && isset($metadata['height'])
            && $metadata['height'] > 0
            && $metadata['width'] * $metadata['height'] > $ruleset['max_size']
        ) {
            $factor = sqrt($ruleset['max_size'] / ($metadata['width'] * $metadata['height']));

            $ruleset['max_width'] = min($ruleset['max_width'], floor($metadata['width'] * $factor));
            $ruleset['max_height'] = min($ruleset['max_height'], floor($metadata['height'] * $factor));
        }

        if ($isRotated) {
            // Invert max_width and max_height as the picture
            // will be automatically rotated
            $options = [
                'maxW' => $ruleset['max_height'],
                'maxH' => $ruleset['max_width'],
            ];
        } else {
            $options = [
                'maxW' => $ruleset['max_width'],
                'maxH' => $ruleset['max_height'],
            ];
        }

        $originalFileSize = filesize($fileName);
        $tempFileInfo = null;
        $tempFileInfo = $gifCreator->imageMagickConvert($fileName, $destExtension, '', '', $imParams, '', $options, true);
        if (filesize($tempFileInfo[3]) >= $originalFileSize - 10240 && $destExtension === $fileExtension) {
            // Conversion leads to same or bigger file (rounded to 10KB to accomodate tiny variations in compression) => skip!
            $tempFileInfo = null;
        }
        if ($tempFileInfo) {
            // Signal to post-process the image
            $this->signalSlotDispatcher->dispatch(
                __CLASS__,
                'afterImageResize',
                [
                    'operation' => ($fileName === $destFileName) ? 'RESIZE' : 'RESIZE_CONVERT',
                    'source' => $fileName,
                    'destination' => $tempFileInfo[3],
                    'newWidth' => &$tempFileInfo[0],
                    'newHeight' => &$tempFileInfo[1],
                ]
            );

            $newFileSize = filesize($tempFileInfo[3]);
            $this->reportAdditionalStorageClaimed($originalFileSize - $newFileSize);

            // Replace original file
            @unlink($fileName);
            @rename($tempFileInfo[3], $destFileName);

            if ($fileName === $destFileName) {
                $message = sprintf(
                    $this->localize('LLL:EXT:image_autoresize/Resources/Private/Language/locallang.xlf:message.imageResized'),
                    $targetFileName, $tempFileInfo[0], $tempFileInfo[1]
                );
            } else {
                $message = sprintf(
                    $this->localize('LLL:EXT:image_autoresize/Resources/Private/Language/locallang.xlf:message.imageResizedAndRenamed'),
                    $targetFileName, $tempFileInfo[0], $tempFileInfo[1], PathUtility::basename($targetDestFileName)
                );
            }

            // Indexation in TYPO3 6.2 is using another signal, after the file
            // has been actually uploaded
            $this->lastMetadata['COMPUTED']['Width'] = $tempFileInfo[0];
            $this->lastMetadata['COMPUTED']['Height'] = $tempFileInfo[1];

            if ($isRotated && (bool)$ruleset['keep_metadata'] === true && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] === 'gm') {
                ImageUtility::resetOrientation($destFileName);
            }

            // Inform FAL about new image size and dimensions
            try {
                $destinationFile = ResourceFactory::getInstance()->retrieveFileOrFolderObject($destFileName);
                if ($destinationFile instanceof File) {
                    $indexer = $this->getIndexer($destinationFile->getStorage());
                    $indexer->updateIndexEntry($destinationFile);
                }
            } catch (FolderDoesNotExistException $e) {
                // We are in upload process. Do nothing
            }

            $this->notify($callbackNotification, $message, \TYPO3\CMS\Core\Messaging\FlashMessage::INFO);
        } else {
            // Destination file was not written
            $destFileName = $fileName;
        }
        return $destFileName;
    }
Processes upload of a file.

@param string $fileName Full path to the file to be processed
@param string $targetFileName Expected target file name, if not converted (only file name, no path)
@param string $targetDirectory
@param \TYPO3\CMS\Core\Resource\File $file
@param \TYPO3\CMS\Core\Authentication\BackendUserAuthentication $backendUser
@param callback $callbackNotification Callback to send notification
@return string File name that was finally written