{"id":185,"date":"2007-09-13T15:30:11","date_gmt":"2007-09-13T22:30:11","guid":{"rendered":"http:\/\/www.stevenbrown.ca\/blog\/archives\/185"},"modified":"2007-11-13T15:38:53","modified_gmt":"2007-11-13T22:38:53","slug":"exifpy-and-image-orientation","status":"publish","type":"post","link":"https:\/\/www.stevenbrown.ca\/blog\/archives\/185","title":{"rendered":"EXIF.py and Image Orientation"},"content":{"rendered":"<p>I was really puzzled&#8230; and in fact, I&#8217;m still puzzled, but at least it works now.<\/p>\n<p><strong>Update<\/strong>: I&#8217;m a bit less puzzled now.  I wasn&#8217;t using the correct version of EXIF.py (see comments).  This post has been updated to correct any information.  I also updated the <code>CODE<\/code> style because posting python code when whitespace is ignored is a little confusing.  ^.^<\/p>\n<p>I&#8217;m <em>now<\/em> using <a href=\"http:\/\/sourceforge.net\/projects\/exif-py\/\">EXIF.py<\/a> for loading EXIF information from photos for my little project, <a href=\"https:\/\/www.stevenbrown.ca\/blog\/archives\/183\">PhotoFile<\/a>.  Today, I wanted the image orientation information.  Looking in the source of EXIF.py, you&#8217;ll find:<\/p>\n<p><code><br \/>\nEXIF_TAGS={<br \/>\n\t...<br \/>\n\t0x0112: ('Orientation',<br \/>\n\t\t{1: 'Horizontal (normal)',<br \/>\n\t\t 2: 'Mirrored horizontal',<br \/>\n\t\t 3: 'Rotated 180',<br \/>\n\t\t 4: 'Mirrored vertical',<br \/>\n\t\t 5: 'Mirrored horizontal then rotated 90 CCW',<br \/>\n\t\t 6: 'Rotated 90 CW',<br \/>\n\t\t 7: 'Mirrored horizontal then rotated 90 CW',<br \/>\n\t\t 8: 'Rotated 90 CCW'}),<br \/>\n\t...<br \/>\n\t0x9003: ('DateTimeOriginal', ),<br \/>\n\t...<br \/>\n\t}<br \/>\n<\/code><\/p>\n<p>So, I tried:<\/p>\n<p><code><br \/>\nimage = open(\"photo.jpg\", \"rb\")<br \/>\ntags = EXIF.process_file(image)<br \/>\n<\/code><\/p>\n<div style=\"text-decoration: line-through;\">\nUsing <code>tags[\"DateTimeOriginal\"]<\/code> works fine.  But using <code>tags[\"Orientation\"]<\/code> does not work.  So finally (it took an unfortunate amount of time to do this), I tried:<\/p>\n<p><code><br \/>\nfor tag in tags.keys():<br \/>\n\tif \"orientation\" in str(tag).lower(): print tag<br \/>\n<\/code>\n<\/div>\n<p>To correct the above, I&#8217;m a little lazy with composition, so it&#8217;s easier to just post some output from a python session:<\/p>\n<p><code><br \/>\n&gt;$ python<br \/>\n&gt;&gt;&gt;  import EXIF<br \/>\n&gt;&gt;&gt;  p = open(\"photo.jpg\", \"rb\")<br \/>\n&gt;&gt;&gt;  tags = EXIF.process_file(p)<br \/>\n&gt;&gt;&gt;  for key in tags.keys():<br \/>\n...\tif \"orientation\" in str(key).lower() or \\<br \/>\n...\t\"datetime\" in str(key).lower(): print key, \": \", tags[key]<br \/>\n...<br \/>\nEXIF DateTimeOriginal :  2006:03:19 14:22:40<br \/>\nImage DateTime :  2006:03:19 14:22:40<br \/>\nEXIF DateTimeDigitized :  2006:03:19 14:22:40<br \/>\nImage Orientation :  Rotated 90 CCW<br \/>\n<\/code><\/p>\n<p>There is indeed no &#8220;Orientation&#8221; tag but there is an &#8220;Image Orientation&#8221; tag.  The string &#8220;Image Orientation&#8221; appears nowhere in the source, and I couldn&#8217;t find any documentation on it.  It looks like the tag keys are set by <span style=\"text-decoration: line-through;\">reading them from the EXIF information within the file<\/span> appending the key to the classification (as pointed out by Shirley &#8211; see comments), but even the <a href=\"http:\/\/park2.wakwak.com\/~tsuruzoh\/Computer\/Digicams\/exif-e.html\">EXIF spec<\/a> lists the tag as &#8220;Orientation&#8221;.  If anybody <span style=\"text-decoration: line-through;\">knows why this is the case<\/span> wants to clarify further, please post in the comments.<\/p>\n<h3>Conclusion<\/h3>\n<p>So if you&#8217;re using <a href=\"http:\/\/sourceforge.net\/projects\/exif-py\/\">EXIF.py<\/a> and want access to the image&#8217;s <em>orientation<\/em>, <strong>use &#8220;Image Orientation&#8221; for the key<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was really puzzled&#8230; and in fact, I&#8217;m still puzzled, but at least it works now. Update: I&#8217;m a bit less puzzled now. I wasn&#8217;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&hellip; <a class=\"more-link\" href=\"https:\/\/www.stevenbrown.ca\/blog\/archives\/185\">Continue reading <span class=\"screen-reader-text\">EXIF.py and Image Orientation<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[3,11],"tags":[48,33,49,47,46],"class_list":["post-185","post","type-post","status-publish","format-standard","hentry","category-geek","category-projects","tag-code","tag-development","tag-exif","tag-photofile","tag-python","entry"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4jEMb-2Z","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.stevenbrown.ca\/blog\/wp-json\/wp\/v2\/posts\/185","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.stevenbrown.ca\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.stevenbrown.ca\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.stevenbrown.ca\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.stevenbrown.ca\/blog\/wp-json\/wp\/v2\/comments?post=185"}],"version-history":[{"count":0,"href":"https:\/\/www.stevenbrown.ca\/blog\/wp-json\/wp\/v2\/posts\/185\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.stevenbrown.ca\/blog\/wp-json\/wp\/v2\/media?parent=185"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.stevenbrown.ca\/blog\/wp-json\/wp\/v2\/categories?post=185"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.stevenbrown.ca\/blog\/wp-json\/wp\/v2\/tags?post=185"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}