comparison core/images/utils.py @ 971:4f265f61874b

Hotlink image form is functioning. The user can now submit a URL via a form and the URL will be downloaded and uploaded to a S3 bucket if it is an image. Tests to follow.
author Brian Neal <bgneal@gmail.com>
date Tue, 22 Sep 2015 20:23:50 -0500
parents core/image.py@24fc302f9076
children
comparison
equal deleted inserted replaced
970:bd594bcba5eb 971:4f265f61874b
1 """
2 This file contains common utility functions for manipulating images for
3 the rest of the applications in the project.
4 """
5 from PIL import ImageFile
6 from PIL import Image
7
8
9 def parse_image(file):
10 """
11 Returns a PIL Image from the supplied Django file object.
12 Throws IOError if the file does not parse as an image file or some other
13 I/O error occurred.
14
15 """
16 parser = ImageFile.Parser()
17 for chunk in file.chunks():
18 parser.feed(chunk)
19 image = parser.close()
20 return image
21
22
23 def downscale_image_square(image, size):
24 """
25 Scale an image to the square dimensions given by size (in pixels).
26 The new image is returned.
27 If the image is already smaller than (size, size) then no scaling
28 is performed and the image is returned unchanged.
29
30 """
31 # don't upscale
32 if (size, size) >= image.size:
33 return image
34
35 (w, h) = image.size
36 if w > h:
37 diff = (w - h) / 2
38 image = image.crop((diff, 0, w - diff, h))
39 elif h > w:
40 diff = (h - w) / 2
41 image = image.crop((0, diff, w, h - diff))
42 image = image.resize((size, size), Image.ANTIALIAS)
43 return image
44
45
46 # Various image transformation functions:
47 def flip_horizontal(im):
48 return im.transpose(Image.FLIP_LEFT_RIGHT)
49
50 def flip_vertical(im):
51 return im.transpose(Image.FLIP_TOP_BOTTOM)
52
53 def rotate_180(im):
54 return im.transpose(Image.ROTATE_180)
55
56 def rotate_90(im):
57 return im.transpose(Image.ROTATE_90)
58
59 def rotate_270(im):
60 return im.transpose(Image.ROTATE_270)
61
62 def transpose(im):
63 return rotate_90(flip_horizontal(im))
64
65 def transverse(im):
66 return rotate_90(flip_vertical(im))
67
68 # From http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html
69 # EXIF Orientation tag values:
70 # 1 = Horizontal (normal)
71 # 2 = Mirror horizontal
72 # 3 = Rotate 180
73 # 4 = Mirror vertical
74 # 5 = Mirror horizontal and rotate 270 CW
75 # 6 = Rotate 90 CW
76 # 7 = Mirror horizontal and rotate 90 CW
77 # 8 = Rotate 270 CW
78
79 ORIENT_FUNCS = {
80 2: flip_horizontal,
81 3: rotate_180,
82 4: flip_vertical,
83 5: transpose,
84 6: rotate_270,
85 7: transverse,
86 8: rotate_90,
87 }
88
89 ORIENT_TAG = 0x112
90
91
92 def orient_image(im):
93 """Transforms the given image according to embedded EXIF data.
94
95 The image instance, im, should be a PIL Image.
96 If there is EXIF information for the image, and the orientation tag
97 indicates that the image should be transformed, perform the transformation.
98
99 Returns a tuple of the form (flag, image) where flag is True if the image
100 was oriented and False otherwise. image is either a new transformed image or
101 the original image instance.
102
103 """
104 if hasattr(im, '_getexif'):
105 try:
106 exif = im._getexif()
107 except IndexError:
108 # Work around issue seen in Pillow
109 # https://github.com/python-pillow/Pillow/issues/518
110 exif = None
111
112 if exif and ORIENT_TAG in exif:
113 orientation = exif[ORIENT_TAG]
114 func = ORIENT_FUNCS.get(orientation)
115 if func:
116 return (True, func(im))
117
118 return (False, im)