Make WordPress Core

Opened 5 years ago

Last modified 4 days ago

#14459 reviewing enhancement

Rotate Full Size Images on Upload

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


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 (2)

14459.patch (1.3 KB) - added by msaggiorato 5 months ago.
Fix with GD Library
14459.diff (2.4 KB) - added by wpdavis 8 weeks ago.

Download all attachments as: .zip

Change History (36)

#1 @Otto42
5 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:

#2 @nacin
5 years ago

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

#3 @mrroundhill
5 years ago

  • Keywords mobile added

#4 @azaozz
5 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
5 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
4 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
4 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
4 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
4 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
4 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 4 years ago by azaozz (previous) (diff)

#11 @Otto42
4 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
4 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
4 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
3 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
3 years ago

  • Cc merty92@… added

#16 follow-up: @azaozz
3 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 3 years ago by azaozz (previous) (diff)

#17 @azaozz
3 years ago

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

#18 @nacin
3 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
3 years ago

  • Cc ercoli@… added
  • Keywords mobile added

#21 follow-up: @webmystery
3 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
3 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
20 months 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.

12 months ago

#25 @helen
10 months ago

#28676 was marked as a duplicate.

5 months ago

Fix with GD Library

#26 @msaggiorato
5 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 5 months ago by msaggiorato (previous) (diff)

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

5 months ago

#28 @oliver033
2 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
2 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
8 weeks ago

#33051 was marked as a duplicate.

8 weeks ago

#31 @wpdavis
8 weeks 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 8 weeks ago by wpdavis (previous) (diff)

#32 @msaggiorato
8 weeks 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
7 weeks 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
4 days ago


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.

Note: See TracTickets for help on using tickets.