EXIF.py and Image Orientation

I was really puzzled… and in fact, I’m still puzzled, but at least it works now.

Update: I’m a bit less puzzled now. I wasn’t using the correct version of EXIF.py (see comments). This post has been updated to correct any information. I also updated the CODE style because posting python code when whitespace is ignored is a little confusing. ^.^

I’m now using EXIF.py for loading EXIF information from photos for my little project, PhotoFile. Today, I wanted the image orientation information. Looking in the source of EXIF.py, you’ll find:


EXIF_TAGS={
...
0x0112: ('Orientation',
{1: 'Horizontal (normal)',
2: 'Mirrored horizontal',
3: 'Rotated 180',
4: 'Mirrored vertical',
5: 'Mirrored horizontal then rotated 90 CCW',
6: 'Rotated 90 CW',
7: 'Mirrored horizontal then rotated 90 CW',
8: 'Rotated 90 CCW'}),
...
0x9003: ('DateTimeOriginal', ),
...
}

So, I tried:


image = open("photo.jpg", "rb")
tags = EXIF.process_file(image)

Using tags["DateTimeOriginal"] works fine. But using tags["Orientation"] does not work. So finally (it took an unfortunate amount of time to do this), I tried:


for tag in tags.keys():
if "orientation" in str(tag).lower(): print tag

To correct the above, I’m a little lazy with composition, so it’s easier to just post some output from a python session:


>$ python
>>> import EXIF
>>> p = open("photo.jpg", "rb")
>>> tags = EXIF.process_file(p)
>>> for key in tags.keys():
... if "orientation" in str(key).lower() or \
... "datetime" in str(key).lower(): print key, ": ", tags[key]
...
EXIF DateTimeOriginal : 2006:03:19 14:22:40
Image DateTime : 2006:03:19 14:22:40
EXIF DateTimeDigitized : 2006:03:19 14:22:40
Image Orientation : Rotated 90 CCW

There is indeed no “Orientation” tag but there is an “Image Orientation” tag. The string “Image Orientation” appears nowhere in the source, and I couldn’t find any documentation on it. It looks like the tag keys are set by reading them from the EXIF information within the file appending the key to the classification (as pointed out by Shirley – see comments), but even the EXIF spec lists the tag as “Orientation”. If anybody knows why this is the case wants to clarify further, please post in the comments.

Conclusion

So if you’re using EXIF.py and want access to the image’s orientation, use “Image Orientation” for the key.

4 comments

  1. Shirley: The image file header has a section called IFD
    the python library appends the IFD header to each of the tags….
    it’s like xml, <Image> is the parent of <Orientation>

    Steven: aaah….
    well, it’s not very useful.
    đŸ˜›

    Shirley: no
    in a image viewer, if you view the EXIF

    Steven: /me grabs venti caramel frapp from fridge

    Shirley: you can see the properties are categorized under different sections
    those sections are the IFDs
    Image, Thumbnail, MakerNote

    Sent at 5:22 PM on Thursday
    Steven: yeah
    i see i see

    Sent at 5:22 PM on Thursday
    Steven: you didn’t want to leave that as a comment?

    Shirley: whatever

    Steven: hah

    Shirley: I will just copy and paste the chat log

    Steven: sure, go ahead

  2. After a bit more discussion, it seemed like Shirley and I were using different versions of EXIF.py… but we were both using the one I linked to on my blog, right? Nope!

    Aarrgh… I was using a different version of EXIF.py from when I was debugging something!! (I have 3 different versions in my folder.) After switching back to the SourceForge.net version (the version you should use) what I had added in my program broke. >.< Oh well, quick fixes. Thanks Shirley, for helping me figure that out. It makes a bit more sense now. đŸ˜€ I have to update this post....

  3. A couple points …

    You can run EXIF.py in command line on test images to see how the library will return those values.

    for example:
    $ ./EXIF.py -d -t Orientation test.jpg
    […snip…]
    Image Orientation (Short): Horizontal (normal)

    This has helped me out several times when trying to figure out which key to use.

    The ‘Orientation’ tag is in the ‘image’ IFD because modifying the image afterwards can (should) change its value. Normally tags in the EXIF IFD do not change even after being modified.

    If you make modifications to EXIF.py which you feel would be useful to others, please submit a patch

    Cheers

Leave a comment

Your email address will not be published. Required fields are marked *