AutoRotation based on EXIF information

moover - August 31, 2009 - 13:44
Project:Imagecache Actions
Version:6.x-1.x-dev
Component:Canvas Actions Module
Category:feature request
Priority:normal
Assigned:Unassigned
Status:reviewed & tested by the community
Description

Would this be hard to implement considering the rotation feature already exists? It would be good if the original file can be left unmodified, then imagecache can generate the thumbnail or display image with the correct orientation without any user input.

Couldn't find any documentation here about it, or any issues but did find the patch http://drupal.org/node/173498 for imageField which seems related.

Thanks.

#1

moover - August 31, 2009 - 13:49
Project:ImageCache» Imagecache Actions
Version:6.x-2.x-dev» 6.x-1.x-dev

Moved to right project.

#2

moover - August 31, 2009 - 13:49
Component:Miscellaneous» Canvas Actions Module

#3

dman - August 31, 2009 - 14:06

Actually, I heard about this being done just recently.
I've been getting deep deep into EXIF and metadata, extracting info that then gets exposed or becomes a parameter on the imagecache process (mostly intextactions - to label them with captions and stuff)

BUT ... I have not yet seen what this rotation tag might be, and what it looks like. Basically my camera doesn't do that, so I'm in the dark about what this is supposed to work like.
Any hints?

#4

moover - August 31, 2009 - 16:08

It was just would be nice thought since picasa is able to know the rotation of images on my desktop without any input from me. If you want an image that has the info i can get you one no problem.

#5

moover - August 31, 2009 - 21:18

Quick browse and I found exiftool http://www.sno.phy.queensu.ca/~phil/exiftool/ which used on one of my pictures shows a variety of output including "Orientation: Rotate 90 CW"

#6

moover - August 31, 2009 - 21:46

File with 90 degree CW rotation tag available at http://moover.co.uk/irvinestown/P1020148.JPG. Couldn't upload it here since it's bigger than 1M.

#7

moover - August 31, 2009 - 22:04

Useful reading: http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html
TagID 0x0112
TagName Orientation
Writable int16u
Group IFD0
1 = Horizontal (normal)
2 = Mirror horizontal
3 = Rotate 180
4 = Mirror vertical
5 = Mirror horizontal and rotate 270 CW
6 = Rotate 90 CW
7 = Mirror horizontal and rotate 90 CW
8 = Rotate 270 CW

#8

dman - August 31, 2009 - 22:05

My previous work with metadata from images
Code is in my sandbox

... currently tuned towards adding text from metadata fields, but if you paste up one of those images you describe, I'll see if we can find and expose the value.

jonathan_hunt said he had an implementation of this task last month. I didn't take him up on it at the time...

#9

dman - August 31, 2009 - 22:07

TagName Orientation - OK, THAT is a useful reference.
I know that site - strange that it's the only/best EXIF reference out. Bloody intimidating list of random crap from various manufacturers!

#10

dman - August 31, 2009 - 22:30

Dammit. My meta_inspector can see the value, but something internal (PHP - exif function?) is already translating it to English.
Scanning the node for meta fields I get:

Orientation (Array, 1 element)
      exif:0 (String, 128 characters )
            No Flip, Rotated 90 degrees clockwise (Row 0 is at the visual right-hand side of of the image, and column 0 is the visual top)

... which is correct, but I'd rather trust the constant...

... Ah, It's my code, I've got the choice available to me... Hm, how to expose both? I'll see...

#11

jonathan_hunt - August 31, 2009 - 23:18

FYI, here's the code I have. It might be a useful starting point. It only works on JPEGs for now. It's sufficient for my purposes; I'm using it to autorotate photographs submitted by iPhone and Android to FixMyStreet.org.nz

AttachmentSize
imagecache_autorotate.zip 3.57 KB

#12

dman - September 1, 2009 - 00:17

Thanks Jonathan, that looks WONDERFULLY simple.
And it's just sweet as a standalone one-action module.
I might just add a paragraph of documentation, but I'd be happy to roll that into the distro if that's OK with you?

#13

dman - September 1, 2009 - 00:33

Actually, on test, that code turned that sample image upside-down!
So it's TRYING ... but I need to review those constants ;-)

#14

jonathan_hunt - September 4, 2009 - 04:50

Doh, I haven't seen that happen. Can you share the test image?

#15

dman - September 4, 2009 - 05:22

That one in this issue: http://moover.co.uk/irvinestown/P1020148.JPG
I don't HAVE any others with that info embedded :0)
edit --- Damn, the sample has gone away.
edit --- damn, I can't edit my local copy of that sample down to a decent size WITHOUT it autocorrecting the orientation in PS, FW, Gimp, Xee .... Maybe I'll try imagemagick

#16

dman - September 4, 2009 - 05:55

this one went through. Same EXIF tags as the orig

AttachmentSize
P1020148-magicked.jpg 287.53 KB

#17

moover - September 4, 2009 - 11:36

Sorry, was tidying up. Will stick up some test images for you later.

#18

moover - September 4, 2009 - 19:26

4 images in http://moover.co.uk/testimages/
I rotated the camera through the four 90 degree increments
Picasa rotates each one correctly on preview to have the arrow pointing up

#19

dman - September 4, 2009 - 23:25

Cool I'm seeing what I should see.
Screenshot shows teasers containing a normal thumbnail, and an embedded, autorotated (scaled) imagecache version of the same.

AttachmentSize
autorotate test.png 92.05 KB

#20

dman - September 4, 2009 - 23:32
Status:active» reviewed & tested by the community

I've committed that to CVS then, please try it out.
Because I've had to swap the rotate-left, rotate-right behaviour from jonathans original (to get the correct result above), I'm harbouring doubts that some cameras may disagree about rotation - does "rotated clcokwise" mean the camera or the image went clockwise? :-)

#21

moover - September 6, 2009 - 18:57

Have upgraded to latest dev snapshot but don't see any rotation happening. Is there a config to turn this on? Thanks

I'd have thought the rotation tag is the rotation needing applied to the image to make it upright eg the original image posted in this thread needs 90 clockwise to make it display right. Just a guess - i've not looked into it and I've not got images from a second camera with the tag to test.

#22

dman - September 6, 2009 - 21:39

It's an action you can turn on.

visit admin - modules.
enable 'imagecache autorotate'
visit or create an imagecache preset
enable 'autorotate' as an action in that preset

#23

moover - September 7, 2009 - 07:18

Not seeing AutoRotate as an option in the actions list. I upgraded from the stable release, though when i ran the updates script it didn't say the usual "... upgraded 1...", it was ".... upgraded 0...". Dev version looks installed ok, the right version is picked up in the module available updates page.

Any ideas what i did wrong? Thanks

#24

dman - September 7, 2009 - 07:31

imagecache_actions is a collection of smaller modules. "Imagecache Autorotate" needs to be turned on explicitly.
It's possible that imagecache is caching things too hard again. :(
Yeah, could be. OK, for no good reason ...
1. disable canvasactions, or an existing unused actions module.
2. uninstall it! using admin/build/modules/uninstall (don't delete anything)
3. enable it again.

That should have fooled imagecache enough.

I'm rolling in a hard cache-flush to the module install function now. imagecache is annoying that way.

#25

moover - September 7, 2009 - 11:16

That's the business now. Working well for me. Didn't realise it was a separate module in the module list that needed enabled. Can't say whether or not it was there after first upgrade but it was after following your instructions. Thanks again.

#26

dman - September 7, 2009 - 11:24

Because it's such a rare case, and because conceptually I don't really know where to put it, and because jonathan_hunt supplied it as a tiny, working, stand-alone optional module ... it's on its own for now.
I don't want to proliferate small modules too much, but OTOH, it's unlikely that any sane site would want more than two or three effects in effect at once, so I don't want to bulk out the extras either. Not sure where to draw the line, but in the meantime, smaller and modular is easier to keep track of changes in :-)

#27

dman - September 9, 2009 - 13:47

FYI, I was just reading National Information Standards Organization (NISO) Z39.87 Technical Metadata for Digital Still Images for fun*.
And found a fuller description on page 70:

orientation
Definition a data element that designates the orientation of the image, with respect to the placement of its rows (7.1.1 imageWidth) and columns (7.1.2 imageHeight), as it was saved to disk
Type enumerated type (restricted to list)
Obligation R
Repeatable N

Values
1 = normal*
2 = normal, image flipped
3 = normal, rotated 180°
4 = normal, image flipped, rotated 180°
5 = normal, image flipped, rotated cw 90°
6 = normal, rotated ccw 90°
7 = normal, image flipped, rotated ccw 90°
8 = normal, rotated cw 90°
9 = unknown
NOTE: “cw” = clockwise; “ccw”= counterclockwise

Notes Values for this field are drawn from terminology from common image processing software. Definitions are as follows:
“Normal” is defined as follows: when opened, the top (0th) row of pixels corresponds to the visual top of the image and the first (0th) column of pixels on left corresponds to the visual left-hand side of the image.
“Image Flipped” is defined as the mirror image of “normal.” (Some software tools call this “image flipped horizontal.”
This field is to be used to record only the orientation value of the stored image, not the orientation of the source to the device (e.g., camera) at the time of capture, or the correct orientation for rendering the image to a display device.

I interpret "the orientation value of the stored image" and "6 = normal, rotated ccw 90° " to mean the image is currently 90° ccw and to transform it for accurate display, we must turn it back 90° cw
Which is what the code I modified currently does

<?php
   
switch($exif['Orientation']) {
      case
3:
       
$degrees = 180;
        break;
      case
6:
       
$degrees = 90; // Rotate 90 CW
       
break;
      case
8:
       
$degrees = 270// Rotate 270 CW
       
break;
      default:
       
$degrees = 0;
    }
    if (
$degrees) {
     
imageapi_image_rotate($image, $degrees);
    }
?>

I think we are right.
I'm a little concerned that that wasn't the case with the version that was working for jonathan, so I won't stake my life on it, but I'll bet 5:1 odds.

* - Actually I was reading up on Library of Congress MARC Data Schemes and that 171-page document on image encodings was comparatively light reading!

 
 

Drupal is a registered trademark of Dries Buytaert.