[FEATURE] Preserve image rotation if orient is saved in exif 79/48079/13
authorStefan Froemken <froemken@gmail.com>
Wed, 11 May 2016 13:58:25 +0000 (15:58 +0200)
committerMarkus Klein <markus.klein@typo3.org>
Fri, 18 May 2018 14:06:59 +0000 (16:06 +0200)
Some digicams like iPhone do not rotate images
by default. They add a direction entry into the exif
meta data.

ImageMagick can read this entry if -auto-orient is set.

The patch add the rotation detection to the ImageInfo object and the
IM/GD commands that read files.

Resolves: #69274
Releases: master
Change-Id: I4b1193daf1c321a3d4beb8d76974012ee42470f6
Reviewed-on: https://review.typo3.org/48079
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Frans Saris <franssaris@gmail.com>
Tested-by: Frans Saris <franssaris@gmail.com>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
typo3/sysext/core/Classes/Imaging/GraphicalFunctions.php
typo3/sysext/core/Classes/Type/File/ImageInfo.php
typo3/sysext/core/Classes/Utility/CommandUtility.php
typo3/sysext/core/Documentation/Changelog/master/Feature-69274-PreserveImageRotationIfOrientIsSavedInExif.rst [new file with mode: 0644]

index b6c8a51..8459588 100644 (file)
@@ -201,11 +201,11 @@ class GraphicalFunctions
     protected $saveAlphaLayer = false;
 
     /**
-     * ImageMagick scaling command; "-geometry" or "-sample". Used in makeText() and imageMagickConvert()
+     * ImageMagick scaling command; "-auto-orient -geometry" or "-auto-orient -sample". Used in makeText() and imageMagickConvert()
      *
      * @var string
      */
-    public $scalecmd = '-geometry';
+    public $scalecmd = '-auto-orient -geometry';
 
     /**
      * Used by v5_blur() to simulate 10 continuous steps of blurring
index 0dbcc16..5cfd90a 100644 (file)
@@ -53,15 +53,41 @@ class ImageInfo extends FileInfo implements LoggerAwareInterface
     }
 
     /**
+     * Gets the image size, considering the exif-rotation present in the file
+     *
+     * @param string $imageFile The image filepath
+     * @return array|false Returns an array where [0]/[1] is w/h.
+     */
+    protected function getExifAwareImageSize(string $imageFile)
+    {
+        $size = false;
+        if (function_exists('getimagesize')) {
+            $size = @getimagesize($imageFile);
+        }
+        if ($size === false) {
+            return false;
+        }
+        [$width, $height] = $size;
+
+        if (function_exists('exif_read_data')) {
+            $exif = @exif_read_data($imageFile);
+            // see: http://sylvana.net/jpegcrop/exif_orientation.html
+            if (isset($exif['Orientation']) && $exif['Orientation'] >= 5 && $exif['Orientation'] <= 8) {
+                return [$height, $width];
+            }
+        }
+
+        return [$width, $height];
+    }
+
+    /**
      * @return array
      */
     protected function getImageSizes()
     {
         if ($this->imageSizes === null) {
-            $this->imageSizes = false;
-            if (function_exists('getimagesize')) {
-                $this->imageSizes = @getimagesize($this->getPathname());
-            }
+            $this->imageSizes = $this->getExifAwareImageSize($this->getPathname());
+
             // Try SVG first as SVG size detection with IM/GM leads to an error output
             if ($this->imageSizes === false && $this->getMimeType() === 'image/svg+xml') {
                 $this->imageSizes = $this->extractSvgImageSizes();
index 3e693c5..1f7f8a4 100644 (file)
@@ -125,6 +125,10 @@ class CommandUtility
                 $parameters = str_replace('###SkipStripProfile###', '', $parameters);
             }
         }
+        // Add -auto-orient on convert so IM/GM respects the image orient
+        if ($parameters && $command === 'convert') {
+            $parameters = '-auto-orient ' . $parameters;
+        }
         // set interlace parameter for convert command
         if ($command !== 'identify' && $gfxConf['processor_interlace']) {
             $parameters = '-interlace ' . $gfxConf['processor_interlace'] . ' ' . $parameters;
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-69274-PreserveImageRotationIfOrientIsSavedInExif.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-69274-PreserveImageRotationIfOrientIsSavedInExif.rst
new file mode 100644 (file)
index 0000000..422d70c
--- /dev/null
@@ -0,0 +1,25 @@
+.. include:: ../../Includes.txt
+
+====================================================================
+Feature: #69274 - Preserve image rotation if orient is saved in exif
+====================================================================
+
+See :issue:`69274`
+
+Description
+===========
+
+Many photo cameras nowadays store pictures in the native sensor orientation.
+The real orientation is stored as meta information in the EXIF data.
+
+TYPO3 now recognizes this image orientation and uses it when reading the image dimensions and
+uses this info when scaling/cropping (processing) the image.
+
+
+Impact
+======
+
+Images with an orientation other than 0 degrees are now properly scaled/cropped (processed).
+Thumbnails in the Backend and processed images in the Frontend are presented in the correct orientation.
+
+.. index:: FAL, ext:core
\ No newline at end of file