Skip to main content

EXIF Orientation Handling Is a Ghetto

Mình thấy nội dung này hay nên copy qua trang để lưu trữ và share cho các bạn. Có thể xem nội dung gốc tại đây.

One of my favourite services at the moment is Transloadit, who provide an image processing API that works a treat on top of platforms like Heroku, where there are strict request timeout limits that make large uploads difficult. They handle auto-orientation of images automagically by default, and normally I’m not even aware of it happening during testing since my camera and OSX also handle auto-orientation transparently.
Recently one particular image stuck out on the staging server as un-rotated, while it worked fine locally using ImageMagick/Dragonfly. Not only that, but the width and height seemed to be wrong, warping the image (the app I’m working on uses a tiled layout, and requires the width and height of each image to be explicitly set in CSS).
I put together a few test images, and have been talking it over via email with Transloadit for the last couple of days (who’ve been super-helpful), and just for kicks thought I’d try uploading the test images to a few other sites to see how everyone else handles it. So began a descent into EXIF madness…

Eh? EXIF Orientation?

The EXIF (exchangeable image file format) standard specifies a set of tags that can be embedded in images (among other things). One of these tags specifies the orientation of the photo, and has 8 possible values which cover every possible combination of rotation and mirroring of an image. This enables you to take a picture with your camera sideways or upside-down (or even inside-out), and stand a reasonable chance of having it display properly on your computer.
This diagram from 80sidea explains the 8 orientations pretty succinctly:

Sounds simple enough…

The problem is that there doesn’t seem to be any consensus on how to handle these orientation tags on the web. Results vary wildly across sites, between different products from the same company, between browsers, and even within a single browser depending on context (yes I’m looking at you Safari). Images with the same orientation value may also be rotated differently on some sites depending on whether they’re landscape or portrait.
Yet another complication is that the seemingly basic concepts of width and heightbecome a bit more abstract when you throw orientation tags into the mix. Is a 640x480 landscape picture with a 90° rotation tag technically landscape or portrait? Is it 640x480 or 480x640? (Short answer - it depends).
Consider the following ImageMagick example using a (technically) ‘Landscape’ image, with an orientation tag value of 5 that makes it a ‘Portrait’ image:

1
2
3
4
5
> identify Portrait_5.jpg
Portrait_5.jpg JPEG 600x450 600x450+0+0 8-bit DirectClass 134KB 0.000u 0:00.009
> convert Portrait_5.jpg -auto-orient Portrait_5_Oriented.jpg
> identify Portrait_5_Oriented.jpg
Portrait_5_Oriented.jpg JPEG 450x600 450x600+0+0 8-bit DirectClass 130KB 0.000u 0:00.000

According to ImageMagick, the original image is 600x450, and the second (auto-oriented) image is 450x600. According to OSX however, they’re both 450x600. Who is correct? I have no idea.
"Landscape tagged with orientation 5 on the left, auto-oriented on the right."

Without further ado…

Let’s take a look at how some of the biggest names on the internet handle EXIF orientation tags. All of the screenshots are of Chrome on OSX unless otherwise specified. A couple of the screenshots (e.g. Gmail) have been cropped and joined for ease of viewing as they are normally displayed as a vertical list, but none of the test images within the screenshots have been altered in any way.
Some of the sites on the ‘bad’ list are of the didn’t-even-try variety, which is possibly one of the saner reactions to this problem and not necessarily ‘bad’. I do feel there should be a consensus on how to handle this though.
The test images are all available on GitHub - try uploading them to your own site to experience the fun first-hand (the good news is that if you’re using ImageMagick you’re probably ok… -auto-orient seems pretty solid apart from the width/height reporting).

The Bad

Surprisingly, Google tops the list here (and how), failing to even display images tagged with 4 out of the 8 orientations in the EXIF standard (the four mirrored orientations). They’re clearly using a centralized image-handling service across Google+, Blogger and Picasa.

Google Plus

Broken.
"Google Plus"

Blogger

Broken.
"Blogger"

Picasa

Broken.
"Picasa"

Google Drive

Didn’t even try - a reasonable approach for a file storage service I guess.
"Google Drive"

Gmail

This is a composite of screenshots laid side-by-side, since they’re usually in a vertical list.
  • Gets tag values 1, 2, 3 and 4 right for landscape pictures (these only involve 0° or 180° rotations, so the aspect-ratio doesn’t change).
  • Fails to rotate 90° rotated landscape images (tag values 5, 6, 7 and 8).
  • Handles portrait tag values 1, 5, 6 and 8 ok (odd, since 6 and 8 don’t work for landscape images), but not 2, 3, 4 or 7 (odd, since 3 and 4 do work for landscape images).
"Gmail"

Dropbox

Handles rotation ok, but not mirroring. This is a composite of large-sized image screenshots, since the thumbnails were too small to make out.
"Dropbox"

Github

GitHub is interesting because it highlights some of the differences that can occur even within the same browser. In desktop Safari, images are not rotated in the context of an HTML page, but the same image is auto-rotated when opened in a new tab by itself (there’s a long discussion related to this on the webkit bug tracker):
"Github on desktop Safari"
On mobile safari however, the orientation tags are interpreted correctly in the context of an HTML page, which trips up GitHub since they’re obviously depending on dimensions returned by something like ImageMagick, which have width and height swapped for 90°-tagged images (note the mis-matched checkered background on landscape-5):
"Github on mobile Safari"

Posterous

Posterous appear to have mirroring figured out, but choke on 90° rotation tags (5, 6, 7 and 8) for landscape images. Interestingly, portrait image rotation for tag values 5, 6, 7 and 8 works. Posterous was the only service to accidentally (I assume) crop photos - portrait-5 and portrait-7. This is a composite image, since the thumbnail view was too small to make out.
"Posterous"

SmugMug

This is a weird one - they’ve managed to rotate all of the ‘mirrored’ images (tag values 2, 4, 5 and 7) 180° so they appear upside-down. They do appear to have un-mirrored them though.
"SmugMug"

Imgur

Close, but chokes on 90° rotated, mirrored images (tag values 5 and 7). A half-SmugMug, if you will.
"Imgur"

Snapfish

The same problems as Posterous, but without the random cropping.
"Snapfish"

SkyDrive

Didn’t even try. As a file storage service, fair enough I guess.
"SkyDrive"

Pinterest

Didn’t even try.
"Pinterest"

Tumblr

Didn’t even try.
"Tumblr"

WordPress.com

Didn’t even try.
"WordPress.com"

Shutterfly

Didn’t even try.
"Shutterfly"

Close, but no cigar

I forgot about 500px.com originally - thanks to Sebastion in the comments for mentioning them. They get all of the rotation and mirroring right, but have a couple of unexpected cropping issues with mirrored, 90°-rotated images (tag values 5 & 7).
"500px"
They don’t have the same problem when viewing a larger version of the image however, which is interesting:
"500px"
Better than most.

The Good

Only a couple of the sites I looked at handle orientation as you’d expect. No great surprises with the first 3 considering their heavy photo pedigree, but nice to see TwitPic on the list.

Facebook

"Facebook"

Flickr

"Flickr"

Photoshop.com

"Photoshop.com"

TwitPic

"TwitPic"

So what?

Web Standards.
However, people smarter than I’ll ever hope to be have been wrestling with this for a while by the look of it:
There’s also some suggestion of ditching the EXIF orientation tag entirely, and putting the onus on device makers to rotate photos properly. This could be problematic for embedded devices with memory or CPU restrictions, but I imagine most modern cameras and phones could manage it.
With the rise of smartphone cameras, where portrait is the default orientation, the problem is only going to get worse. I don’t claim to have any answers, but the one thing that stands out is that every site out there is re-inventing the wheel, and a lot of them are getting it wrong.
If Google can’t handle images consistently across their own sites, on a browser that they built, what hope do the rest of us have?

Comments

Popular posts from this blog

Phân biệt biến kiểu Property, Public, Protected, Private trong ngôn ngữ Objective C

- Theo kinh nghiệm làm việc của mình với các bạn trong nhóm khi lập trình Objective-C và cũng đọc qua code của những project cũ. Ít khi nào mọi người để ý và khai báo đúng với ý đồ của từng đối tượng, và vi phạm quy tắc tính đóng gói, tính bảo mật thông tin của đối tượng trong lập trình hướng đối tượng (Tham khảo lý thuyết Lập trình hướng đối tượng tại trang Wiki ). - Theo ngôn ngữ lập trình Java, người ta khuyến khích mỗi khi dùng biến kiểu public thì nên đặt 1 biến private và hỗ trợ những hàm getter/setter để truy suất biến private đó.     + Nguyên nhân họ nói là đảm bảo tính đóng gói, và nếu sau này có thay đổi gì trên biến đó bạn có thể sửa được dễ dàng, chi tiết về vấn đề này ở đây .     + Nói tóm tại thì nguyên nhân chính là có thể kiểm soát được truy xuất đến giá trị của 1 đối tượng từ bên ngoài, có thể dễ dàng mở rộng code bằng cách override lại những hàm getter/setter. - Các bạn có thể áp dụng nguyên tắc đó từ bên Java qua ngôn ngữ lập trình Object...

(Kinh nghiệm) Auto layout và Size classes trong iOS - Phần 1

Trước đây khi viết những ứng dụng chạy trên nhiều màn hình hoặc hỗ trợ màn hình xoay ngang, xoay dọc mọi người hay dùng code để có thể chỉnh được những vị trí cũng như kích thước của những đối tượng. Hoặc có thể dùng Autosizing để tự động canh chỉnh những đối tượng nhưng không tối ưu và tiện lợi cho lắm, hình minh hoạ ở dưới: Vì thế từ lúc Apple phát hành ra iPhone 5, iPhone 5s với kích thước màn hình là 4 inch, làm phát sinh thêm vấn đề " Làm thế nào ta có thể thiết kế giao diện có thể chạy được trên nhiều màn hình? " mà không làm thay đổi nhiều code để có thể dễ dàng bảo trì ứng dụng. Apple mới phát triển chức năng Auto Layout và Size Classes để thực hiện nhiệm vụ này. Nếu bạn đã quen dùng Autosizing để thiết kế giao diện thì bạn có thể vẫn sử dụng chúng. Nhưng tuỳ theo từng dự án mà khách hàng hay người PM hoặc leader của bạn muốn bạn dùng công nghệ mới Auto Layout và Size Classes   để làm layout trên iOS mà không cần dùng bất cứ đoạn code nào và chỉ viết trên 1 storyboard...

(Căn bản) Bài 1: Hướng dẫn tạo tài khoản Apple ID và iTune không cần thẻ Visa hoặc MasterCard

Nếu bạn muốn lập trình trên iOs hoặc trên MacOs thì bạn nên có tài khoản Apple ID và tài khoản iTune. Sẽ hữa ích cho bạn khi cài đặt và nân cấp chương trình XCode. Nhưng khó khăn ở chỗ nếu bạn không có thẻ Visa hoặc Master Card, mà vẫn muốn có tài khoản để có thể cài ứng dụng trên AppStore. Sau đây mình xin hướng dẫn cách tạo tài khoản mà không cần những thẻ đó và có thể tạo tài khoản trên những store ở các nước khác. Đầu tiên bạn mở chương trình iTune lên và vào tab "App Store", sau đó bạn kiếm chương trình nào Free và nhấn vào đó nó sẽ hiển thị ra màn hình như sau:    Khi đang ở màn hình này bạn nhấn vào chữ "Free" bên dưới hình sẽ hiển thị ô cho bạn nhập Apple ID và Password.Vì bạn chưa có nên hãy nhấn vào nút "Create Apple ID" để tạo tài khoản. Sau khi bạn nhấn vào nút "Create Apple ID" bạn sẽ qua màn hình như bên dưới. Tại đây bạn có thể chuyển AppStore của các nước (Vì có những chương trình chỉ cài được trên từng AppStore mỗi nước thôi) hi...