changeset 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 1e44691932b2
children f31168465953
files core/image.py core/image_uploader.py
diffstat 2 files changed, 73 insertions(+), 0 deletions(-) [+]
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)
--- a/core/image_uploader.py	Thu Oct 02 19:07:07 2014 -0500
+++ b/core/image_uploader.py	Sat Oct 04 13:43:22 2014 -0500
@@ -12,6 +12,7 @@
 from PIL import Image
 
 from core.functions import temp_open
+from core.image import orient_image
 
 
 logger = logging.getLogger(__name__)
@@ -63,6 +64,12 @@
             temp_file.write(chunk)
         temp_file.close()
 
+        # Re-orient if necessary
+        image = Image.open(temp_name)
+        changed, image = orient_image(image)
+        if changed:
+            image.save(temp_name)
+
         # Resize image if necessary
         if new_size:
             image = Image.open(temp_name)