37 |
37 |
38 else : |
38 else : |
39 # this thumb doesn't exist or is older |
39 # this thumb doesn't exist or is older |
40 return True |
40 return True |
41 |
41 |
42 @property |
42 def calcsize (self, size) : |
43 def size (self) : |
|
44 """ |
43 """ |
45 Compute the *real* size of this thumbnail, from the image's actual size and our target size. |
44 Compute the *real* size of this thumbnail, from the give actual size and our target size. |
46 |
45 |
47 Preserves the aspect ratio etc. |
46 Preserves the aspect ratio etc. |
48 """ |
47 """ |
49 |
48 |
50 # real image size |
49 # initial image size |
51 img_width, img_height = self.image.img_size |
50 width, height = size |
52 |
51 |
53 # target size |
52 # target size |
54 thumb_width, thumb_height = self.target_size |
53 thumb_width, thumb_height = self.target_size |
55 |
54 |
56 # calc new size, preserving aspect ratio |
55 # calc new size, preserving aspect ratio |
57 if img_width > thumb_width : |
56 # calculations ripped from PIL.Image.thumbnail :) |
58 height = max(img_height * thumb_width / img_width, 1) |
57 if width > thumb_width : |
|
58 height = max(height * thumb_width / width, 1) |
59 width = thumb_width |
59 width = thumb_width |
60 |
60 |
61 elif img_height > thumb_height : |
61 if height > thumb_height : |
62 width = max(img_width * thumb_height / img_height, 1) |
62 width = max(width * thumb_height / height, 1) |
63 height = thumb_height |
63 height = thumb_height |
64 |
64 |
65 return width, height |
65 return width, height |
66 |
66 |
67 ## operations |
67 ## operations |
68 def resize (self, img) : |
68 def resize (self, img) : |
69 """ |
69 """ |
70 Resize the give image as needed. |
70 Resize the given image as needed. |
71 """ |
71 """ |
72 |
72 |
73 return img.resize(self.size, resample=PIL.Image.ANTIALIAS) |
73 return img.resize(self.calcsize(img.size), resample=PIL.Image.ANTIALIAS) |
74 |
74 |
75 def auto_orient (self, img, orient_info) : |
75 def transform (self, img, orient_info) : |
76 """ |
76 """ |
77 Automatically orient the image using the given orientation info. |
77 Transform this image into the output version, resizing, rotating and mirroring in a single step. |
78 """ |
78 """ |
|
79 |
|
80 # get sizes |
|
81 img_width, img_height = img_size = img.size |
79 |
82 |
80 # unpack |
83 # unpack |
81 mirroring, rotation = orient_info |
84 mirroring, rotation = orient_info |
|
85 |
|
86 if mirroring : |
|
87 # XXX: does anyone actually use this? Untested |
|
88 # interaction with rotate is probably wrong |
|
89 p0, p1 = { |
|
90 exif.MIRROR_HORIZONTAL: ((0, img_height), (img_width, 0)), |
|
91 exif.MIRROR_VERTICAL: ((img_width, 0), (0, img_height)), |
|
92 } |
82 |
93 |
|
94 if rotation in (exif.ROTATE_90, exif.ROTATE_270) : |
|
95 # flip the dimensions to take rotate into account |
|
96 img_size = img_height, img_width |
|
97 |
|
98 # calc new size |
|
99 thumb_size = self.calcsize(img_size) |
|
100 |
|
101 if rotation in (exif.ROTATE_90, exif.ROTATE_270) : |
|
102 # flip the dimensions back before rotate |
|
103 thumb_size = thumb_size[1], thumb_size[0] |
|
104 |
83 if mirroring : |
105 if mirroring : |
84 # XXX: does anyone actually use this? |
106 # perform the transform, can't use ANTIALIAS here :/ |
85 pass |
107 img = img.transform(thumb_size, PIL.Image.EXTENT, p0 + p1, PIL.Image.NEAREST) |
|
108 |
|
109 else : |
|
110 # resize with ANTIALIAS |
|
111 img = img.resize(thumb_size, resample=PIL.Image.ANTIALIAS) |
86 |
112 |
87 if rotation : |
113 if rotation : |
|
114 # transform can't rotate |
88 # since these are in steps of 90 degrees, it should keep the right size |
115 # since these are in steps of 90 degrees, it should keep the right size |
89 # but gah, PIL wants these as counter-clockwise! |
116 # but gah, PIL wants these as counter-clockwise! |
90 img = img.rotate(360 - rotation) |
117 img = img.rotate(360 - rotation) |
91 |
118 |
92 # ok |
|
93 return img |
119 return img |
94 |
120 |
95 def update (self) : |
121 def update (self) : |
96 """ |
122 """ |
97 Render new output thumbnail. |
123 Render new output thumbnail. |
98 """ |
124 """ |
99 |
125 |
100 # start with origional image |
126 # start with origional image |
101 img = self.image.img |
127 img = self.image.img |
102 |
128 |
103 # create resized copy of main image, using our size |
129 if self.image.orientation and (self.image.orientation[0] or self.image.orientation[1]) : |
104 img = self.resize(img) |
130 # rotate |
|
131 img = self.transform(img, self.image.orientation) |
105 |
132 |
106 # got orientation info? |
133 else : |
107 if self.image.orientation : |
134 # just create resized copy of main image, using our size |
108 img = self.auto_orient(img, self.image.orientation) |
135 img = self.resize(img) |
109 |
136 |
110 # write it out |
137 # write it out |
111 img.save(self.path) |
138 img.save(self.path) |
112 |
139 |