2011-05-29 14:18:03 +00:00
|
|
|
# Created By: Virgil Dupras
|
|
|
|
# Created On: 2011-05-29
|
2012-03-15 18:28:40 +00:00
|
|
|
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
2011-05-29 14:18:03 +00:00
|
|
|
#
|
|
|
|
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
|
|
|
# which should be included with this package. The terms are also available at
|
|
|
|
# http://www.hardcoded.net/licenses/bsd_license
|
|
|
|
|
2012-08-10 20:34:27 +00:00
|
|
|
import logging
|
2011-05-29 14:18:03 +00:00
|
|
|
from hscommon.util import get_file_ext
|
|
|
|
from core import fs
|
2011-05-31 14:05:12 +00:00
|
|
|
from . import exif
|
2011-05-29 14:18:03 +00:00
|
|
|
|
|
|
|
class Photo(fs.File):
|
|
|
|
INITIAL_INFO = fs.File.INITIAL_INFO.copy()
|
|
|
|
INITIAL_INFO.update({
|
|
|
|
'dimensions': (0,0),
|
2012-08-10 20:34:27 +00:00
|
|
|
'exif_timestamp': '',
|
2011-05-29 14:18:03 +00:00
|
|
|
})
|
2012-05-29 21:39:54 +00:00
|
|
|
__slots__ = fs.File.__slots__ + tuple(INITIAL_INFO.keys())
|
|
|
|
|
2011-05-29 14:18:03 +00:00
|
|
|
# These extensions are supported on all platforms
|
|
|
|
HANDLED_EXTS = {'png', 'jpg', 'jpeg', 'gif', 'bmp', 'tiff', 'tif'}
|
|
|
|
|
2011-05-31 14:05:12 +00:00
|
|
|
def _plat_get_dimensions(self):
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
def _plat_get_blocks(self, block_count_per_side, orientation):
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
def _get_orientation(self):
|
|
|
|
if not hasattr(self, '_cached_orientation'):
|
|
|
|
try:
|
2012-08-10 20:34:27 +00:00
|
|
|
with self.path.open('rb') as fp:
|
2011-05-31 14:05:12 +00:00
|
|
|
exifdata = exif.get_fields(fp)
|
|
|
|
# the value is a list (probably one-sized) of ints
|
|
|
|
orientations = exifdata['Orientation']
|
|
|
|
self._cached_orientation = orientations[0]
|
|
|
|
except Exception: # Couldn't read EXIF data, no transforms
|
|
|
|
self._cached_orientation = 0
|
|
|
|
return self._cached_orientation
|
|
|
|
|
2011-05-29 14:18:03 +00:00
|
|
|
@classmethod
|
|
|
|
def can_handle(cls, path):
|
|
|
|
return fs.File.can_handle(path) and get_file_ext(path[-1]) in cls.HANDLED_EXTS
|
|
|
|
|
2011-05-31 14:05:12 +00:00
|
|
|
def _read_info(self, field):
|
|
|
|
fs.File._read_info(self, field)
|
|
|
|
if field == 'dimensions':
|
|
|
|
self.dimensions = self._plat_get_dimensions()
|
|
|
|
if self._get_orientation() in {5, 6, 7, 8}:
|
|
|
|
self.dimensions = (self.dimensions[1], self.dimensions[0])
|
2012-08-10 20:34:27 +00:00
|
|
|
elif field == 'exif_timestamp':
|
|
|
|
try:
|
|
|
|
with self.path.open('rb') as fp:
|
|
|
|
exifdata = exif.get_fields(fp)
|
|
|
|
self.exif_timestamp = exifdata['DateTimeOriginal']
|
|
|
|
except Exception:
|
|
|
|
logging.info("Couldn't read EXIF of picture: %s", self.path)
|
2011-05-31 14:05:12 +00:00
|
|
|
|
2011-05-29 14:18:03 +00:00
|
|
|
def get_blocks(self, block_count_per_side):
|
2011-05-31 14:05:12 +00:00
|
|
|
return self._plat_get_blocks(block_count_per_side, self._get_orientation())
|
2011-05-29 14:18:03 +00:00
|
|
|
|