[BUGFIX] LocalCropScaleMaskHelper consumes too much memory when cropping 89/43389/3
authorThomas Maroschik <tmaroschik@dfau.de>
Thu, 17 Sep 2015 09:35:39 +0000 (11:35 +0200)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Thu, 17 Sep 2015 20:51:43 +0000 (22:51 +0200)
When using the new image crop functionality in the backend the
LocalCropScaleMaskHelper crops the image using gdlib functions. Those
functions load the whole image into memory and can lead to fatal
errors because of memory limits in case of large images.

This fix replaces the gdlib functions with according ImageMagick/
GraphicsMagick functions which crop the image outside of PHP's
memory.

Resolves: #68484
Releases: master
Change-Id: I390264838ebfd89701f860302a07b3f5895d46ac
Reviewed-on: http://review.typo3.org/43389
Reviewed-by: Mathias Schreiber <mathias.schreiber@wmdb.de>
Tested-by: Mathias Schreiber <mathias.schreiber@wmdb.de>
Reviewed-by: Andreas Bouche <andreas.bouche@flagbit.de>
Reviewed-by: Frans Saris <franssaris@gmail.com>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/core/Classes/Resource/Processing/LocalCropScaleMaskHelper.php

index 7c71b78..4b83b14 100644 (file)
@@ -85,11 +85,26 @@ class LocalCropScaleMaskHelper {
                                $crop = $configuration['crop'];
                        }
 
-                       $im = $gifBuilder->imageCreateFromFile($originalFileName);
-                       $croppedImage = GeneralUtility::tempnam('crop_', '.' . $sourceFile->getExtension());
-                       $gifBuilder->crop($im, ['crop' => $crop]);
-                       if ($gifBuilder->ImageWrite($im, $croppedImage)) {
-                               $originalFileName = $croppedImage;
+                       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];
                        }
                }