1
0
mirror of https://github.com/gryf/pygtktalog.git synced 2025-12-17 19:40:21 +01:00

* Refactored Img and Thumnail classes for new media storage.

This commit is contained in:
2008-11-02 19:48:22 +00:00
parent 301161926f
commit e9edb602e3
2 changed files with 94 additions and 215 deletions

View File

@@ -24,76 +24,49 @@
from shutil import copy from shutil import copy
from os import path, mkdir from os import path, mkdir
from hashlib import sha512
from tempfile import mkstemp
from utils import EXIF
import Image import Image
class Img(object): class Img(object):
def __init__(self, filename=None, base=''): def __init__(self, filename, base=''):
self.root = 'images' self.root = 'images'
self.x = 160 self.x = 160
self.y = 160 self.y = 160
self.filename = filename self.filename = filename
self.base = base self.base = base
f = open(filename, "r")
self.sha512 = sha512(f.read()).hexdigest()
f.close()
def save(self, image_id): def save(self):
"""Save image and asociated thumbnail into specific directory structure """Save image and asociated thumbnail into specific directory structure
return full path to the file and thumbnail or None""" returns filename for image"""
base_path = self.__get_and_make_path(image_id)
ext = self.filename.split('.')[-1].lower()
image_filename = path.join(self.base, base_path + "." + ext)
thumbnail = path.join(self.base, base_path + "_t.jpg") image_filename = path.join(self.base, self.sha512)
thumbnail = path.join(self.base, self.sha512 + "_t")
returncode = -1 # check wheter image already exists
if path.exists(image_filename) and path.exists(thumbnail):
if __debug__:
print "image", self.filename, "with hash", self.sha512, "already exist"
return self.sha512
if not path.exists(thumbnail):
im = self.__scale_image() im = self.__scale_image()
if im:
im.save(thumbnail, "JPEG") im.save(thumbnail, "JPEG")
returncode = 1
if returncode != -1:
# copy image # copy image
if not path.exists(image_filename):
copy(self.filename, image_filename) copy(self.filename, image_filename)
return thumbnail, image_filename, returncode return self.sha512
# private class functions # private class functions
def __get_and_make_path(self, img_id):
"""Make directory structure regards of id
and return filepath and img filename WITHOUT extension"""
t = path.join(self.base, self.root)
try: mkdir(t)
except: pass
h = hex(img_id)
if len(h[2:])>6:
try: mkdir(path.join(t, h[2:4]))
except: pass
try: mkdir(path.join(t, h[2:4], h[4:6]))
except: pass
fpath = path.join(t, h[2:4], h[4:6], h[6:8])
try: mkdir(fpath)
except: pass
img = "%s" % h[8:]
elif len(h[2:])>4:
try: mkdir(path.join(t, h[2:4]))
except: pass
fpath = path.join(t, h[2:4], h[4:6])
try: mkdir(fpath)
except: pass
img = "%s" % h[6:]
elif len(h[2:])>2:
fpath = path.join(t, h[2:4])
try: mkdir(fpath)
except: pass
img = "%s" % h[4:]
else:
fpath = ''
img = "%s" % h[2:]
return(path.join(t, fpath, img))
def __scale_image(self): def __scale_image(self):
"""create thumbnail. returns image object or None""" """create thumbnail. returns image object or None"""
try: try:

View File

@@ -22,189 +22,95 @@
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
from tempfile import gettempdir from tempfile import mkstemp
from hashlib import sha512
from shutil import move from shutil import move
from os import path, mkdir from os import path
from datetime import datetime import sys
from utils import EXIF from utils import EXIF
import Image import Image
class Thumbnail(object): class Thumbnail(object):
"""Class for generate/extract thumbnail from image file"""
def __init__(self, filename=None, x=160, y=160, def __init__(self, filename=None, base=''):
root='thumbnails', base=''): self.thumb_x = 160
self.root = root self.thumb_y = 160
self.x = x
self.y = y
self.filename = filename self.filename = filename
self.base = base self.base = base
self.sha512 = sha512(open(filename).read()).hexdigest()
self.thumbnail_path = path.join(self.base, self.sha512 + "_t")
def save(self, image_id): def save(self):
"""Save thumbnail into specific directory structure """Save thumbnail into specific directory structure
return full path to the file and exif object or None""" return filename base and exif object or None"""
filepath = path.join(self.base, self.__get_and_make_path(image_id)) exif = {}
f = open(self.filename, 'rb') orientations = {2: Image.FLIP_LEFT_RIGHT, # Mirrored horizontal
exif = None 3: Image.ROTATE_180, # Rotated 180
returncode = -1 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: try:
exif = EXIF.process_file(f) exif = EXIF.process_file(image_file)
f.close()
if 'JPEGThumbnail' in exif:
thumbnail = exif['JPEGThumbnail']
f = open(filepath,'wb')
f.write(thumbnail)
f.close()
if 'Image Orientation' in exif:
orientation = exif['Image Orientation'].values[0]
if orientation > 1:
# TODO: replace silly datetime function with tempfile
ms = datetime.now().microsecond
t = path.join(gettempdir(), "thumb%d.jpg" % ms)
im_in = Image.open(filepath)
im_out = None
if orientation == 8:
# Rotated 90 CCW
im_out = im_in.transpose(Image.ROTATE_90)
elif orientation == 6:
# Rotated 90 CW
im_out = im_in.transpose(Image.ROTATE_270)
elif orientation == 3:
# Rotated 180
im_out = im_in.transpose(Image.ROTATE_180)
elif orientation == 2:
# Mirrored horizontal
im_out = im_in.transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 4:
# Mirrored vertical
im_out = im_in.transpose(Image.FLIP_TOP_BOTTOM)
elif orientation == 5:
# Mirrored horizontal then rotated 90 CCW
op = Image.FLIP_LEFT_RIGHT
rot = Image.ROTATE_90
im_out = im_in.transpose(op).transpose(rot)
elif orientation == 7:
# Mirrored horizontal then rotated 90 CW
op = Image.FLIP_LEFT_RIGHT
rot = Image.ROTATE_270
im_out = im_in.transpose(op).transpose(rot)
if im_out:
im_out.save(t, 'JPEG')
move(t, filepath)
else:
f.close()
returncode = 0
else:
im = self.__scale_image()
if im:
im.save(filepath, "JPEG")
returncode = 1
except: except:
f.close() if __debug__:
im = self.__scale_image() print "exception", sys.exc_info()[0], "raised with file:"
if im: print self.filename
im.save(filepath, "JPEG") finally:
returncode = 2 image_file.close()
return filepath, exif, returncode
# private class functions if path.exists(self.thumbnail_path):
def __get_and_make_path(self, image_id): if __debug__:
"""Make directory structure regards of id print "file", self.filename, "with hash", self.sha512, "exists"
and return filepath WITHOUT extension""" return self.sha512, exif
t = path.join(self.base, self.root)
try: mkdir(t) if 'JPEGThumbnail' in exif:
except: pass if __debug__:
h = hex(image_id) print self.filename, "exif thumb"
if len(h[2:])>6: exif_thumbnail = exif['JPEGThumbnail']
try: mkdir(path.join(t, h[2:4])) thumb_file = open(self.thumbnail_path, 'wb')
except: pass thumb_file.write(exif_thumbnail)
try: mkdir(path.join(t, h[2:4], h[4:6])) thumb_file.close()
except: pass
fpath = path.join(t, h[2:4], h[4:6], h[6:8]) if 'Image Orientation' in exif:
try: mkdir(fpath) orient = exif['Image Orientation'].values[0]
except: pass if orient > 1 and orient in orientations:
img = "%s.%s" % (h[8:], 'jpg') temp_image_path = mkstemp()[1]
elif len(h[2:])>4:
try: mkdir(path.join(t, h[2:4])) thumb_image = Image.open(self.thumbnail_path)
except: pass tmp_thumb_img = thumb_image.transpose(orientations[orient])
fpath = path.join(t, h[2:4], h[4:6])
try: mkdir(fpath) if orient in flips:
except: pass tmp_thumb_img = tmp_thumb_img.transpose(flips[orient])
img = "%s.%s" % (h[6:], 'jpg')
elif len(h[2:])>2: if tmp_thumb_img:
fpath = path.join(t, h[2:4]) tmp_thumb_img.save(temp_image_path, 'JPEG')
try: mkdir(fpath) move(temp_image_path, self.thumbnail_path)
except: pass return self.sha512, exif
img = "%s.%s" %(h[4:], 'jpg')
else: else:
fpath = '' if __debug__:
img = "%s.%s" %(h[2:], 'jpg') print self.filename, "no exif thumb"
return(path.join(t, fpath, img)) thumb = self.__scale_image()
if thumb:
thumb.save(self.thumbnail_path, "JPEG")
return self.sha512, exif
return None, exif
def __scale_image(self): def __scale_image(self):
"""create thumbnail. returns image object or None""" """create thumbnail. returns image object or None"""
try: try:
im = Image.open(self.filename).convert('RGB') image_thumb = Image.open(self.filename).convert('RGB')
except: except:
return None return None
x, y = im.size it_x, it_y = image_thumb.size
if x > self.x or y > self.y: if it_x > self.thumb_x or it_y > self.thumb_y:
im.thumbnail((self.x, self.y), Image.ANTIALIAS) image_thumb.thumbnail((self.thumb_x, self.thumb_y), Image.ANTIALIAS)
return im return image_thumb
def __scale_image_deprecated(self, factor=True):
"""generate scaled Image object for given file
args:
factor - if False, adjust height into self.y
if True, use self.x for scale portrait pictures height.
returns Image object, or None
"""
try:
im = Image.open(self.filename).convert('RGB')
except:
return None
x, y = im.size
if x > self.x or y > self.y:
if x==y:
# square
imt = im.resize((self.y, self.y), Image.ANTIALIAS)
elif x > y:
# landscape
if int(y/(x/float(self.x))) > self.y:
# landscape image: height is non standard
self.x1 = int(float(self.y) * self.y / self.x)
if float(self.y) * self.y / self.x - self.x1 > 0.49:
self.x1 += 1
imt = im.resize(((int(x/(y/float(self.y))), self.y)),
Image.ANTIALIAS)
elif x/self.x==y/self.y:
# aspect ratio ok
imt = im.resize((self.x, self.y), Image.ANTIALIAS)
else:
imt = im.resize((self.x, int(y/(x/float(self.x)))), 1)
else:
# portrait
if factor:
if y>self.x:
imt = im.resize(((int(x/(y/float(self.x))),self.x)),
Image.ANTIALIAS)
else:
imt = im
else:
self.x1 = int(float(self.y) * self.y / self.x)
if float(self.y) * self.y / self.x - self.x1 > 0.49:
self.x1 += 1
if x/self.x1==y/self.y:
# aspect ratio ok
imt = im.resize((self.x1,self.y),Image.ANTIALIAS)
else:
imt = im.resize(((int(x/(y/float(self.y))), self.y)),
Image.ANTIALIAS)
return imt
else:
return im