diff core/image.py @ 837:234726f5a47a

For issue #74, re-orient uploaded images if necessary.
author Brian Neal <bgneal@gmail.com>
date Sat, 04 Oct 2014 13:43:22 -0500
parents ee87ea74d46b
children 36d988b800c2
line wrap: on
line diff
--- a/core/image.py	Thu Oct 02 19:07:07 2014 -0500
+++ b/core/image.py	Sat Oct 04 13:43:22 2014 -0500
@@ -41,3 +41,69 @@
         image = image.crop((0, diff, w, h - diff))
     image = image.resize((size, size), Image.ANTIALIAS)
     return image
+
+
+# Various image transformation functions:
+def flip_horizontal(im):
+    return im.transpose(Image.FLIP_LEFT_RIGHT)
+
+def flip_vertical(im):
+    return im.transpose(Image.FLIP_TOP_BOTTOM)
+
+def rotate_180(im):
+    return im.transpose(Image.ROTATE_180)
+
+def rotate_90(im):
+    return im.transpose(Image.ROTATE_90)
+
+def rotate_270(im):
+    return im.transpose(Image.ROTATE_270)
+
+def transpose(im):
+    return rotate_90(flip_horizontal(im))
+
+def transverse(im):
+    return rotate_90(flip_vertical(im))
+
+# From http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html
+# EXIF Orientation tag values:
+# 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
+
+ORIENT_FUNCS = {
+    2: flip_horizontal,
+    3: rotate_180,
+    4: flip_vertical,
+    5: transpose,
+    6: rotate_270,
+    7: transverse,
+    8: rotate_90,
+}
+
+ORIENT_TAG = 0x112
+
+
+def orient_image(im):
+    """Transforms the given image according to embedded EXIF data.
+
+    The image instance, im, should be a PIL Image.
+    If there is EXIF information for the image, and the orientation tag
+    indicates that the image should be transformed, perform the transformation.
+
+    Returns a tuple of the form (flag, image) where flag is True if the image
+    was oriented and False otherwise. image is either a new transformed image or
+    the original image instance.
+
+    """
+    if hasattr(im, '_getexif'):
+        exif = im._getexif()
+        if exif and ORIENT_TAG in exif:
+            return (True, ORIENT_FUNCS[ORIENT_TAG](im))
+
+    return (False, im)