mirror of
https://github.com/gryf/pygtktalog.git
synced 2025-12-17 03:20:17 +01:00
115 lines
3.6 KiB
Python
115 lines
3.6 KiB
Python
"""
|
|
Project: pyGTKtalog
|
|
Description: Create thumbnail for sepcified image
|
|
Type: lib
|
|
Author: Roman 'gryf' Dobosz, gryf73@gmail.com
|
|
Created: 2011-05-15
|
|
"""
|
|
|
|
import os
|
|
from tempfile import mkstemp
|
|
import shutil
|
|
|
|
from PIL import Image
|
|
import exifread
|
|
|
|
from pycatalog.logger import get_logger
|
|
|
|
|
|
LOG = get_logger(__name__)
|
|
|
|
|
|
class ThumbCreator(object):
|
|
"""
|
|
Class for generate/extract thumbnail from image file
|
|
"""
|
|
|
|
def __init__(self, filename):
|
|
self.thumb_x = 160
|
|
self.thumb_y = 160
|
|
self.filename = filename
|
|
|
|
def generate(self):
|
|
"""
|
|
Save thumbnail into temporary file
|
|
"""
|
|
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}
|
|
|
|
exif = self._get_exif()
|
|
file_desc, thumb_fn = mkstemp(suffix=".jpg")
|
|
os.close(file_desc)
|
|
|
|
if exif and 'JPEGThumbnail' in exif and exif['JPEGThumbnail']:
|
|
LOG.debug("exif thumb for filename %s" % self.filename)
|
|
exif_thumbnail = exif['JPEGThumbnail']
|
|
thumb = open(thumb_fn, 'wb')
|
|
thumb.write(exif_thumbnail)
|
|
thumb.close()
|
|
else:
|
|
LOG.debug("no exif thumb")
|
|
if self.is_image_smaller():
|
|
shutil.copyfile(self.filename, thumb_fn)
|
|
else:
|
|
thumb = self._scale_image()
|
|
if thumb:
|
|
thumb.save(thumb_fn, "JPEG")
|
|
|
|
if exif and 'Image Orientation' in exif:
|
|
orient = exif['Image Orientation'].values[0]
|
|
if orient > 1 and orient in orientations:
|
|
thumb_image = Image.open(thumb_fn)
|
|
tmp_thumb_img = thumb_image.transpose(orientations[orient])
|
|
|
|
if orient in flips:
|
|
tmp_thumb_img = tmp_thumb_img.transpose(flips[orient])
|
|
|
|
tmp_thumb_img.save(thumb_fn, 'JPEG')
|
|
|
|
return thumb_fn
|
|
|
|
def is_image_smaller(self):
|
|
"""Check if image is smaller than desired dimention, return boolean"""
|
|
image = Image.open(self.filename)
|
|
im_x, im_y = image.size
|
|
image.close()
|
|
return im_x <= self.thumb_x and im_y <= self.thumb_y
|
|
|
|
def _get_exif(self):
|
|
"""
|
|
Get exif (if available), return as a dict
|
|
"""
|
|
image_file = open(self.filename, 'rb')
|
|
try:
|
|
exif = exifread.process_file(image_file)
|
|
except Exception:
|
|
exif = {}
|
|
LOG.info("Exif crashed on '%s'." % self.filename)
|
|
finally:
|
|
image_file.close()
|
|
|
|
return exif
|
|
|
|
def _scale_image(self):
|
|
"""
|
|
Create thumbnail. returns image object or None
|
|
"""
|
|
try:
|
|
image_thumb = Image.open(self.filename).convert('RGB')
|
|
except Exception:
|
|
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
|