The module doesn't work with Imagick toolkit

Created on 17 July 2017, almost 8 years ago
Updated 5 June 2023, about 2 years ago

Tried to use the module with Imagick toolkit (and Image Widget Crop - not sure if it's relevant), discovered that the image is rotated multiple times before it is finally stored (in the original image the building was lying on its left side, when uploaded to site it was lying on its right side).
Discovered two reasons for that:
1. The module uses hook_file_presave (as opposed to hook_file_insert), so the image is processed every time it is [re]saved for whatever reason. In my configuration it was apparently saved two times.
2. As Imagick toolkit doesn't strip the EXIF (unlike GD) and the rotate() operation doesn't reset the Orientation flag in the EXIF, the image will be rotated as many times as it is saved.
Solution:
1. If using Imagick toolkit, use its "autorotate" operaton instead of generic rotate(). In that case you don't need to call exif_read_data() to determine whether the image needs rotating and how many degrees - the toolkit will do it automagically AND it will reset the Orientation flag in the EXIF so that the image won't be autorotated ever again.
2. Use hook_file_insert instead of hook_file_presave. With (1) implemented the image will not be rotated twice anyway, but why call the toolkit many times when it should only be called once.
Here's the code I wound up with for my particular case:

/**
 * Implements hook_file_insert().
 * Rotates an image to its EXIF Orientation.
 * ONLY WORKS WITH IMAGICK TOOLKIT!
 */
function HOOK_file_insert(EntityInterface $file) {
  if ($file->getMimeType() == 'image/jpeg') {
    $image = \Drupal::service('image.factory')->get($file->getFileUri());
    if ($image->getToolkit()->apply("autorotate")) {
      $image->save();
    }
  }
}

Hope this helps someone. Maybe someone will be willing to make a patch that would query the toolkit used and use different code for different toolkits - I'm a bit out of my depth here.

πŸ› Bug report
Status

Active

Version

1.0

Component

Code

Created by

πŸ‡·πŸ‡ΊRussia marassa Moscow

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • ivnish Kazakhstan

    Same problem. I use imagemagick and the module rotating images twice:

    1. When image added to form image widget
    2. When node presave

    When I use -strip I have wrong rotation because I also have file_validate_image_resolution

    I added

    // Remove EXIF.

    $img = new Imagick($path);
    $img->stripImage();
    $img->writeImage($path);

    after

    $image->save();

    And now it works fine for me

  • ivnish Kazakhstan

    $image->getToolkit()->apply("autorotate")

    doesn't work for me (function return FALSE)

  • ivnish Kazakhstan

    Topicstarter helps me in private messages. I installed imagemagick β†’ module, but $image->getToolkit()->apply doesn't work. Needs to install imagick β†’ module instead

    If you need to strip exif you can add code after autorotate

    if ($image->getToolkit()->apply("strip")) {
      $image->save();
    }
  • πŸ‡ΊπŸ‡ΈUnited States chucksimply

    -strip was the reason why images weren't being rotated correctly. Removed it, now working as it should. Drupal 10.2

  • πŸ‡ΊπŸ‡ΈUnited States SocialNicheGuru

    @chucksimply is there a patch?

  • πŸ‡ΊπŸ‡ΈUnited States chucksimply

    So it's not 100% solved. I originally had the -strip option under the Prepend arguments on the Image Toolkit page. Orientation remained incorrect.

    I then removed the -strip option, and now all my image styles that convert to WEBP have the correct orientation. But without the convert, they still are incorrect.

    This isn't really a solution, and I'm not sure what's going on. Still confused.

  • πŸ‡ΊπŸ‡ΈUnited States chucksimply

    Circling back on this issue... found a resolution.

    This issue here πŸ› Orientation is no longer fixed if a maximum image resolution is set on the field RTBC fixes an issue where EXIF data was removed if Max Image Size constraints were defined and executed for an image upload.

    Solution:
    - Apply the patch from the related issue
    - Add -strip to Execution > Prepend arguments, just like in comments #5, #6, #7.

    Now ImageMagick and this module work as expected.

  • πŸ‡¬πŸ‡§United Kingdom adamps

    I now have a patch that hopefully fixes this issue and several others in 🌱 Overall status Active . Please help to test and review.

  • πŸ‡ΊπŸ‡ΈUnited States chucksimply

    Applied merge patch from #19 and removed --strip, now autorotating as it should in 1.5.

  • πŸ‡ͺπŸ‡ΈSpain eduardo morales alberti Spain, πŸ‡ͺπŸ‡Ί

    Created issue to support ImageMagic without adding image_effects as dependency and support drupal 10/11 constraints πŸ› Function file_validate_image_resolution is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Active

  • πŸ‡ͺπŸ‡ΈSpain eduardo morales alberti Spain, πŸ‡ͺπŸ‡Ί

    We created the module https://www.drupal.org/project/exif_removal β†’ to strip the exif information.
    We will also support the strip exif information if the imagemagic tool exists ✨ Support imagemagic to strip the exif information Active

  • πŸ‡©πŸ‡ͺGermany stefan.korn Jossgrund

    I am a bit confused about this issue.

    Firstly I suppose the solution via hook_file_insert given by TO is not considered to be a patch for this module, but rather a separate solution that you could use in your own module. In that case you should not install exif_orientation module.

    The solution is depending on imagick β†’ module and does not work with ImageMagick β†’ module.

    If you use ImageMagick module and Image Effects β†’ module the solution could be changed to this:

    /**
     * Implements hook_file_insert().
     * Rotates an image to its EXIF Orientation.
     * ONLY WORKS WITH IMAGEMAGICK TOOLKIT AND IMAGE_EFFECTS module!
     */
    function HOOK_file_insert(EntityInterface $file) {
      if ($file->getMimeType() == 'image/jpeg') {
        $image = \Drupal::service('image.factory')->get($file->getFileUri());
        if ($image->getToolkit()->apply("auto_orient")) {
          $image->save();
        }
      }
    }
    
    

    Btw:
    I am not sure what's the deal about stripping the EXIF information here. I suppose this is not related to the solution given by TO, but refering to a general issue with exif_orientation module and maybe having multiple rotations. And I agree with tfranz that stripping exif information can be a legal issue and an issue in general. This is kind of data loss, since the exif information is stripped from the image itself forever. This is no solution in my point of view, at most a very bad workaround. An advantage of ImageMagick is that it keeps exif information on image styles, which GD does not. Stripping the exif information would render this advantage useless.

  • πŸ‡ͺπŸ‡ΈSpain eduardo morales alberti Spain, πŸ‡ͺπŸ‡Ί

    @stefan.korn on Issue πŸ› Function file_validate_image_resolution is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Active you have a more complete solution compatible with Drupal 10 and 11.

    We created a new module to remove the EXIF information, but just because some images save geolocation about where it was taken and device information, but is optional and not related to exif_orientation, it is just to give an option to strip the information without losing the rotation.

Production build 0.71.5 2024