# HG changeset patch # User Tero Marttila # Date 1245019018 -10800 # Node ID 74f135774567767b9ca7579233df49b16c58fb70 # Parent cac613118e7597167f7f0e1263fab62cf973ee79 fix rotated size of auto-oriented thumbnails, and throw some code at mirroring - untested diff -r cac613118e75 -r 74f135774567 degal/image.py --- a/degal/image.py Mon Jun 15 01:36:15 2009 +0300 +++ b/degal/image.py Mon Jun 15 01:36:58 2009 +0300 @@ -125,7 +125,7 @@ def cleanup (self) : """ - Drop some cached heavy values + Drop some memory-intensive cached values """ del self.img diff -r cac613118e75 -r 74f135774567 degal/thumbnail.py --- a/degal/thumbnail.py Mon Jun 15 01:36:15 2009 +0300 +++ b/degal/thumbnail.py Mon Jun 15 01:36:58 2009 +0300 @@ -2,7 +2,7 @@ State for thumbnails; derivates of Images """ -import filesystem +import filesystem, exif import PIL.Image @@ -39,27 +39,27 @@ # this thumb doesn't exist or is older return True - @property - def size (self) : + def calcsize (self, size) : """ - Compute the *real* size of this thumbnail, from the image's actual size and our target size. + Compute the *real* size of this thumbnail, from the give actual size and our target size. Preserves the aspect ratio etc. """ - # real image size - img_width, img_height = self.image.img_size + # initial image size + width, height = size # target size thumb_width, thumb_height = self.target_size # calc new size, preserving aspect ratio - if img_width > thumb_width : - height = max(img_height * thumb_width / img_width, 1) + # calculations ripped from PIL.Image.thumbnail :) + if width > thumb_width : + height = max(height * thumb_width / width, 1) width = thumb_width - - elif img_height > thumb_height : - width = max(img_width * thumb_height / img_height, 1) + + if height > thumb_height : + width = max(width * thumb_height / height, 1) height = thumb_height return width, height @@ -67,29 +67,55 @@ ## operations def resize (self, img) : """ - Resize the give image as needed. + Resize the given image as needed. """ - return img.resize(self.size, resample=PIL.Image.ANTIALIAS) + return img.resize(self.calcsize(img.size), resample=PIL.Image.ANTIALIAS) - def auto_orient (self, img, orient_info) : + def transform (self, img, orient_info) : """ - Automatically orient the image using the given orientation info. + Transform this image into the output version, resizing, rotating and mirroring in a single step. """ + # get sizes + img_width, img_height = img_size = img.size + # unpack mirroring, rotation = orient_info - + if mirroring : - # XXX: does anyone actually use this? - pass + # XXX: does anyone actually use this? Untested + # interaction with rotate is probably wrong + p0, p1 = { + exif.MIRROR_HORIZONTAL: ((0, img_height), (img_width, 0)), + exif.MIRROR_VERTICAL: ((img_width, 0), (0, img_height)), + } + + if rotation in (exif.ROTATE_90, exif.ROTATE_270) : + # flip the dimensions to take rotate into account + img_size = img_height, img_width + + # calc new size + thumb_size = self.calcsize(img_size) + + if rotation in (exif.ROTATE_90, exif.ROTATE_270) : + # flip the dimensions back before rotate + thumb_size = thumb_size[1], thumb_size[0] + + if mirroring : + # perform the transform, can't use ANTIALIAS here :/ + img = img.transform(thumb_size, PIL.Image.EXTENT, p0 + p1, PIL.Image.NEAREST) + + else : + # resize with ANTIALIAS + img = img.resize(thumb_size, resample=PIL.Image.ANTIALIAS) if rotation : + # transform can't rotate # since these are in steps of 90 degrees, it should keep the right size # but gah, PIL wants these as counter-clockwise! img = img.rotate(360 - rotation) - # ok return img def update (self) : @@ -100,12 +126,13 @@ # start with origional image img = self.image.img - # create resized copy of main image, using our size - img = self.resize(img) + if self.image.orientation and (self.image.orientation[0] or self.image.orientation[1]) : + # rotate + img = self.transform(img, self.image.orientation) - # got orientation info? - if self.image.orientation : - img = self.auto_orient(img, self.image.orientation) + else : + # just create resized copy of main image, using our size + img = self.resize(img) # write it out img.save(self.path)