# This Python file uses the following encoding: utf-8 # # Author: Roman 'gryf' Dobosz gryf@elysium.pl # # Copyright (C) 2007 by Roman 'gryf' Dobosz # # This file is part of pyGTKtalog. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ------------------------------------------------------------------------- from tempfile import mkstemp from hashlib import sha512 from shutil import move from os import path import sys from lib import EXIF import Image class Thumbnail(object): """Class for generate/extract thumbnail from image file""" def __init__(self, filename=None, base=''): self.thumb_x = 160 self.thumb_y = 160 self.filename = filename self.base = base self.sha512 = sha512(open(filename).read()).hexdigest() self.thumbnail_path = path.join(self.base, self.sha512 + "_t") def save(self): """Save thumbnail into specific directory structure return filename base and exif object or None""" exif = {} orientations = {2: Image.FLIP_LEFT_RIGHT, # Mirrored horizontal 3: Image.ROTATE_180, # Rotated 180 4: Image.FLIP_TOP_BOTTOM, # Mirrored vertical 5: Image.ROTATE_90, # Mirrored horizontal then # rotated 90 CCW 6: Image.ROTATE_270, # Rotated 90 CW 7: Image.ROTATE_270, # Mirrored horizontal then # rotated 90 CW 8: Image.ROTATE_90} # Rotated 90 CCW flips = {7: Image.FLIP_LEFT_RIGHT, 5: Image.FLIP_LEFT_RIGHT} image_file = open(self.filename, 'rb') try: exif = EXIF.process_file(image_file) except: if __debug__: print "exception", sys.exc_info()[0], "raised with file:" print self.filename finally: image_file.close() if path.exists(self.thumbnail_path): if __debug__: print "file", self.filename, "with hash", self.sha512, "exists" return self.sha512, exif if 'JPEGThumbnail' in exif: if __debug__: print self.filename, "exif thumb" exif_thumbnail = exif['JPEGThumbnail'] thumb_file = open(self.thumbnail_path, 'wb') thumb_file.write(exif_thumbnail) thumb_file.close() if 'Image Orientation' in exif: orient = exif['Image Orientation'].values[0] if orient > 1 and orient in orientations: temp_image_path = mkstemp()[1] thumb_image = Image.open(self.thumbnail_path) tmp_thumb_img = thumb_image.transpose(orientations[orient]) if orient in flips: tmp_thumb_img = tmp_thumb_img.transpose(flips[orient]) if tmp_thumb_img: tmp_thumb_img.save(temp_image_path, 'JPEG') move(temp_image_path, self.thumbnail_path) return self.sha512, exif else: if __debug__: print self.filename, "no exif thumb" thumb = self.__scale_image() if thumb: thumb.save(self.thumbnail_path, "JPEG") return self.sha512, exif return None, exif def __scale_image(self): """create thumbnail. returns image object or None""" try: image_thumb = Image.open(self.filename).convert('RGB') except: return None it_x, it_y = image_thumb.size if it_x > self.thumb_x or it_y > self.thumb_y: image_thumb.thumbnail((self.thumb_x, self.thumb_y), Image.ANTIALIAS) return image_thumb