WordPress.org

Make WordPress Core

Opened 6 years ago

Last modified 3 weeks ago

#14459 reviewing enhancement

Rotate Full Size Images on Upload

Reported by: mrroundhill Owned by: azaozz
Milestone: 4.7 Priority: normal
Severity: normal Version: 3.0
Component: Upload Keywords: westi-like mobile has-patch
Focuses: Cc:

Description

It may be worth a revisit to #7042. Some mobile devices that use WordPress for Android are not capturing images in the correct orientation, instead they are writing the EXIF orientation to the image instead (which is a standard method these days). In wp-android and other external clients that offer full size image upload, these images will not be rotated correctly upon upload.

Since most mobile users are on the go with no access to the wp-admin area to rotate the images themselves, it would work best if the image was rotated for them automatically.

Hopefully there's a solution that wouldn't strip the EXIF data, some way to copy the EXIF data before rotating, then save it back again?

Attachments (3)

14459.patch (1.3 KB) - added by msaggiorato 15 months ago.
Fix with GD Library
14459.diff (2.4 KB) - added by wpdavis 12 months ago.
14459.2.diff (2.1 KB) - added by markoheijnen 2 months ago.

Download all attachments as: .zip

Change History (52)

#1 @Otto42
6 years ago

+1, the EXIF Orientation tag is not respected by the image handler. This happens to iPhone images that are uploaded through the media uploader.

Documentation on the tag and the values therein can be found here:
http://sylvana.net/jpegcrop/exif_orientation.html

#2 @nacin
6 years ago

  • Keywords needs-patch added
  • Milestone changed from Awaiting Review to Future Release

#3 @mrroundhill
6 years ago

  • Keywords mobile added

#4 @azaozz
6 years ago

There was an older ticket about this (can't find it at the moment) that had a patch too. Think we didn't do it at the end as many users upload images directly from their cameras and rotating a 10-12 megapixel image was causing PHP to run out of memory.

#5 @Otto42
6 years ago

Related: #11536

Suggestion: Since there is compatibility issues with image rotation, maybe it's worth taking a look at the various functionality we need for image handling and write a wrapper class or two that works based on what support is offered on the host, as well as handling cases where available memory is low and such. Give the most functionality possible given the available functions.

#6 @westi
5 years ago

  • Keywords westi-like 3.4-early added

We should revisit this because it is becoming more and more common for people to want to upload and post quickly without having to manually fix the rotation of images.

#7 @Otto42
5 years ago

Rotating the image is easy enough, but I can't find any way to do this in PHP and keep the EXIF data in the resulting file. So the original unmodified file would have to be saved as well.

Unless I'm missing something.

#8 @dd32
5 years ago

Unless I'm missing something.

Unfortunately, IIRC, GD doesnt support EXIF preservation at all. That's one of the advantages of ImageMagik. Unless of course there's a PHP library to add exif back into the images afterwards.

#9 follow-up: @Otto42
5 years ago

Side note: The new image_resize checkbox will cause the code to strip the EXIF data as well, before it gets read in as the attachment metadata.

#10 in reply to: ↑ 9 @azaozz
5 years ago

Replying to Otto42:

The resizing is actually done with js when supported (most cases) which preserves exif data. Have a look at uploader->features in Firebug's dom tab. Wondering if they will add image rotation there too :)

Last edited 5 years ago by azaozz (previous) (diff)

#11 @Otto42
5 years ago

True, but if the resize isn't done on the client side (not supported case), then it's done in wp_handle_upload, and exif will be lost there.

#12 follow-up: @azaozz
5 years ago

Currently it's supported for all runtimes that we use (HTML5, Flash, Silverlight) except in Safari and Opera when using HTML5 http://www.plupload.com/. Alternatively we can disable resizing in php completely and allow it only when supported on the client side.

#13 in reply to: ↑ 12 @westi
5 years ago

Replying to azaozz:

Currently it's supported for all runtimes that we use (HTML5, Flash, Silverlight) except in Safari and Opera when using HTML5 http://www.plupload.com/. Alternatively we can disable resizing in php completely and allow it only when supported on the client side.

This doesn't really help when images are uploaded not using the uploader - e.g. XML-RPC, or a post-by-email solution - I don't think we should expect all clients to do the rotation for us.

Having it work only a %age of the time is confusing.

#14 @dd32
4 years ago

  • Milestone changed from Future Release to 3.5

Closed #21006 as a duplicate, pulling this into the 3.5 timeline for consideration as that's where the other ticket was.

#15 @merty
4 years ago

  • Cc merty92@… added

#16 follow-up: @azaozz
4 years ago

The best way to handle this in PHP is with jpegtran and exiftool. Both are command line tools available for all platforms, the EXIF is fully preserved (EXIF orientation is reset with exiftool) and the quality of the JPEG is preserved 100%. However using them would also require PHP's exec() to be enabled.

Another option is to rotate only the resized images leaving the original as-is (flikr does this). Perhaps this could be done only for larger JPEG images like photos, larger than the max size.

Yet another option would be to rotate the images on display. In most current browsers this is possible now but will be hard to implement in core.

Last edited 4 years ago by azaozz (previous) (diff)

#17 @azaozz
4 years ago

  • Keywords mobile 3.4-early removed
  • Owner set to azaozz
  • Status changed from new to reviewing

#18 @nacin
4 years ago

  • Milestone changed from 3.5 to Future Release

This requires jpegtran, exiftool, etc. Now that we have WP_Image_Editor, we can do this in a future release.

#19 @daniloercoli
4 years ago

  • Cc ercoli@… added
  • Keywords mobile added

#21 follow-up: @webmystery
4 years ago

It would be nice to fully recognize exif rotation. When a user uploads an exif rotated image the correct image sizes are not created and all of my automatic placement of the featured image /gallery images are displayed at full size, etc... Took me a bit of head scratching to figure out why one image in a particular post was displaying full-size, especially as I was not the one who uploaded it and the user who reported the problem neglected to tell me that hey had to rotate the image after the upload. Regenerating the image sizes didn't work either. I had to re-save the image in photoshop and re-upload it to fix the problem. This would have been impossible for the less geeky to figure out.

#22 in reply to: ↑ 21 @SergeyBiryukov
4 years ago

Replying to webmystery:

the correct image sizes are not created and all of my automatic placement of the featured image /gallery images are displayed at full size, etc...

This sounds like a result of #22985 or #19889.

#23 in reply to: ↑ 16 @henry.wright
2 years ago

I'm seeing this problem more and more - I think perhaps due to my site visitors moving away from their desktops and towards mobile access.

Replying to azaozz:

using them [jpegtran and exiftool] would also require PHP's exec() to be enabled.

Is PHP's exec() usually enabled by default?

Another option is to rotate only the resized images leaving the original as-is

Preserve Exif info on the original but obliterate it on resized images? Sounds the most logical approach

Yet another option would be to rotate the images on display.

Wouldn't this impact performance?

This ticket was mentioned in Slack in #core by simonwheatley. View the logs.


22 months ago

#25 @helen
20 months ago

#28676 was marked as a duplicate.

@msaggiorato
15 months ago

Fix with GD Library

#26 @msaggiorato
15 months ago

I just posted a patch for this, that fixed it in my case.

I implemented it in production for my site using a separate class that extends the load method of WP_Image_Editor_GD. (To avoid touching the WP Core files)

With this fix, original images are kept untouched, and thumbnails are generated correctly. I think the EXIF Orientation head will be lost in thumbnails, but i don't think that's a problem, since they will be in the correct size and orientation now.

PS: I tried several locations in the exif_read_data array, because i've found online that the Orientation header can be present in several places.

This is the first time I post a patch, so if I did something wrong, please let me know.

EDIT: I took the liberty of checking how google does the resizing and generation of thumbnails. And their thumbnails don't have EXIF data either. So i guess as long as we keep the EXIF data in the original file to be read to generate meta data, i think we're cool.

Browsers also implements this funny, if you load one of the "faulty" images in a page, it displays rotated (in the pixel oriented way), but if you load it directly it's in the correct orientation. I've tried this in Chrome Stable 43.0.2357.132 .

Last edited 15 months ago by msaggiorato (previous) (diff)

This ticket was mentioned in Slack in #core by msaggiorato. View the logs.


15 months ago

#28 @oliver033
12 months ago

I would ask that this be looked at. I don't mind that the rotation may be off when I upload but I am frustrated that I when I rotate the image myself in the media gallery after uploading that it does not always respect this rotation in the mobile format of my site.

#29 @heatherleecosta
12 months ago

I would also love a fix for this. Currently my site shows the photos fine on mobile but on desktop, they are sideways. I have multiple users uploading photos daily and most are not computer-savvy. Walking them through the process of editing their photos before upload has been very time consuming and is usually very frustrating for them.

#30 @SergeyBiryukov
12 months ago

#33051 was marked as a duplicate.

@wpdavis
12 months ago

#31 @wpdavis
12 months ago

Just added a patch option that catches this on upload.

However, something weird is going on. It seems the issue is when an image gets rotated but the orientation field in the EXIF data doesn't get changed. I'm not actually sure how to identify this, but if somebody has an idea I'm all ears.

Here are examples of pretty much the same file. test1, if uploaded with the patch applied, will appear correctly. test2, if uploaded with the patch applied, will actually be over-rotated.

http://trunk.wpdavis.com/test1.jpg => Exif: http://trunk.wpdavis.com/test1.php
http://trunk.wpdavis.com/test2.jpg => Exif: http://trunk.wpdavis.com/test2.php

If we figure out a way to identify more conclusively which images need to be rotated, we could always implement it with ImageMagick only to preserve IPTC data.

We've noticed that respect for the orientation field seems to vary by browser, so I think this would be nice to handle in core to make sure all images are properly rotated, if we can grok it.

Last edited 12 months ago by wpdavis (previous) (diff)

#32 @msaggiorato
12 months ago

Back when I posted my patch (which half solved the issue), I kept working on this issue. And came to realize that the GD library is not the best way to solve this issue as there are much more things in place than just the EXIF rotation change.

After a bunch of research about the binary format of JPEG files, i came across this library https://github.com/lsolesen/pel.

With the help of this library, i was able to extract most of the EXIF data from one image, and put it into the corrected image generated by the GD library (that has no EXIF data, or color profile, or any other information).

I also went a bit further and even fixed the thumbnail of the PNG (as it may be required, and it also should be consistent with the full image).

In the end, I managed to make this work at a decent level. But didn't post back the solution here because it involved too much server work and image data binary manipulation, that shouldn't happen if browsers did their job nicely.

I also thought that a solution like the one I implemented wouldn't be totally approved by the community.

I'll try to put together a GitHub gist with my solution as it is now if someone's interested.

#33 @jcmboyer
12 months ago

This problem just started 4 days ago for me. I have photos from my Android and they are turned in my dropbox. When I upload, they are the correct orientation in the post draft. When I preview the post, the image is upside down on my browser (using Chrome). When the post appears on mobile, it's correct. When the post is posted on social media, it's upside down.

I tried adding the image rotation plug in but it doesn't work for the newest version of WP. I am very frustrated as it worked and now it doesn't. I blog daily. I have read this entire thread but am wondering why I have to change the settings on the photos when it worked just fine 4 days ago.

#34 @n7studios
10 months ago

Patch:
https://gist.github.com/n7studios/6a764d46bc1d515ba406

I encountered this problem today, and built a small WordPress Plugin to resolve it which:

  1. Checks for the EXIF orientation flag, to see if the image needs rotating,
  2. Rotates the image, if required,
  3. Writes the EXIF and IPTC data from the original image to the modified, rotated version
  4. Sets the EXIF orientation flag to 1, to prevent applications which read the flag from rotating the image (which would result in over rotation)

I appreciate there's still a lot of work to do, namely:

  1. Submitting this as an actual patch for WordPress core,
  2. Using the WP Filesystem for ovewriting the image file vs. fopen/fwrite wrappers
  3. I'm a bit dubious about line 140, as I think it'd potentially replace any 3, 6 or 8 value with 1 (potentially breaking other EXIF metadata - although in my tests, this didn't happen) - I struggled with hexadecimals:
    $exif_data = str_replace( chr( dechex( $original_orientation ) ) , chr( 0x1 ), $exif_data );
    

This doesn't require any particular PHP extensions / libraries, and most of the code is inspired by this ticket or submissions on php.net, which I've tried to credit where applicable. The main thing is that EXIF / IPTC data is retained - this is typically lost when using GD to edit an image.

Would be great to get some thoughts / feedback and see how this can be improved before submitting as a patch.

This ticket was mentioned in Slack in #core-images by joemcgill. View the logs.


7 months ago

#36 @joemcgill
4 months ago

#36446 was marked as a duplicate.

#37 @divorcetheworld
4 months ago

I suggest taking a look at this plugin, which seems to work for me, even with non-iOs images.

https://wordpress.org/plugins/ios-images-fixer/

Photos taken with some older cameras display fine in Windows Photo viewer, but they appear sideways in the Media Library after upload. With this plugin installed, they appear properly oriented in the Media Library. Unfortunately, the "Crunching" time after upload was fairly long.

#38 @lukecavanagh
2 months ago

Do not know about this issue until today.

This ticket was mentioned in Slack in #core-images by lukecavanagh. View the logs.


2 months ago

#40 @lukecavanagh
2 months ago

Seems like a fix that should have made it into core a while back. So it seems from ticket 21006 that the issue is not on WordPress.com since that was fixed. But the issue is just on self-hosted WordPress.

This ticket was mentioned in Slack in #core-images by markoheijnen. View the logs.


2 months ago

#42 @lukecavanagh
2 months ago

@markoheijnen

The patch applies cleanly.

#43 @msaggiorato
2 months ago

Doesn't rotating the image like the last patch removes the EXIF information of the images? (at least when using GD)

#44 follow-ups: @lukecavanagh
2 months ago

@msaggiorato

You should be able to keep the EXIF information and use

http://php.net/manual/en/imagick.getimageorientation.php

#45 in reply to: ↑ 44 @msaggiorato
2 months ago

@lukecavanagh

I meant the rotate function from the GD library (which as far as i know is the most commonly available everywhere)

When you rotate the exif information of the original file was removed (at least until a year ago, not sure if there's been updates to GD ever since).

This has been discussed in this very same ticket (or related ones) at some point.

One more thing, we're ignoring the rest of the rotation positions (horizontally flipped versions of each one of the other)

This article here should mention all the possible Orientations.

http://www.impulseadventure.com/photo/exif-orientation.html

I hope this helps.

#46 @lukecavanagh
2 months ago

@msaggiorato

Thanks, I read that article last week as well.

#47 in reply to: ↑ 44 @triplejumper12
2 months ago

Replying to lukecavanagh:

@msaggiorato

You should be able to keep the EXIF information and use

http://php.net/manual/en/imagick.getimageorientation.php

Using Imagick's getImageOrientation is probably preferable to using exif_read_data, because exif_read_data can throw an error for some jpegs depending on how they have been modified in the past. getImageOrientation seemed to be more reliable and does the logic of finding the orientation from the exif data itself.

However, getImageOrientation will return the same orientation after an image has been rotated, so you would still have to remove the orientation or set it to 1 after you rotate it. Unfortunately, Imagick doesn't adjust the orientation when you rotate it like GD does.

Thought that might be helpful since I ran into this while trying to fix orientations on upload. I don't have any examples of the images this failed on anymore, but just something you might want to consider.

This ticket was mentioned in Slack in #core-images by joemcgill. View the logs.


3 weeks ago

#49 @joemcgill
3 weeks ago

  • Keywords has-patch added; needs-patch removed
  • Milestone changed from Future Release to 4.7
Note: See TracTickets for help on using tickets.