# HG changeset patch # User Brian Neal # Date 1412448202 18000 # Node ID 234726f5a47a9c779963da006120777606613236 # Parent 1e44691932b20b893046b089bd26a040f76ceb4f For issue #74, re-orient uploaded images if necessary. diff -r 1e44691932b2 -r 234726f5a47a core/image.py --- 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) diff -r 1e44691932b2 -r 234726f5a47a core/image_uploader.py --- 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)