degal/exif.py
changeset 122 292aaba6d6ec
parent 121 3bed35e79f41
child 130 94888270dae0
equal deleted inserted replaced
121:3bed35e79f41 122:292aaba6d6ec
     4 
     4 
     5 from __future__ import with_statement
     5 from __future__ import with_statement
     6 
     6 
     7 import utils
     7 import utils
     8 
     8 
       
     9 MIRROR_NONE         = 0
       
    10 MIRROR_HORIZONTAL   = 1
       
    11 MIRROR_VERTICAL     = 2
       
    12 
       
    13 ROTATE_NONE         = 0
       
    14 ROTATE_90           = 90
       
    15 ROTATE_180          = 180
       
    16 ROTATE_270          = 270
       
    17 
     9 class ExifHandler (object) :
    18 class ExifHandler (object) :
    10     """
    19     """
    11         Our generic interface for Exif data
    20         Our generic interface for Exif data
    12     """
    21     """
    13 
    22 
    16             Load Exif data from the given File.
    25             Load Exif data from the given File.
    17         """
    26         """
    18 
    27 
    19         self.file = file
    28         self.file = file
    20     
    29     
       
    30     def image_tag_value (self, tag, default=None) :
       
    31         """
       
    32             Load and return the raw binary value for the given main image tag.
       
    33         """
       
    34 
       
    35         return default
       
    36 
    21     def image_tag (self, tag, default=None) :
    37     def image_tag (self, tag, default=None) :
    22         """
    38         """
    23             Load and return the human-readable unicode-safe value for the given main image tag.
    39             Load and return the human-readable unicode-safe value for the given main image tag.
    24         """
    40         """
    25 
    41 
    26         abstract
    42         return default
    27 
    43 
    28     def image_tags (self, tags) :
    44     def image_tags (self, tags) :
    29         """
    45         """
    30             Load and return the given tags for the main image as a sequence of (tag, value) tuples , following the same
    46             Load and return the given tags for the main image as a sequence of (tag, value) tuples , following the same
    31             rules as image_tag, except there should mainly be only one call to this function, encompassing all the
    47             rules as image_tag, except there should mainly be only one call to this function, encompassing all the
    39             value = self.image_tag(tag)
    55             value = self.image_tag(tag)
    40 
    56 
    41             # filter out default not-found
    57             # filter out default not-found
    42             if value is not None :
    58             if value is not None :
    43                 yield tag, value
    59                 yield tag, value
       
    60     
       
    61 
       
    62     def get_orientation (self) :
       
    63         """
       
    64             Get the orientation of the image in terms of mirroring and rotation in integer degrees clockwise.
       
    65             
       
    66             Returns a (MIRROR_*, ROTATE_*) tuple, or None if the Orientation tag could not be found.
       
    67 
       
    68             Returns None if it could not be found.
       
    69         """
       
    70         
       
    71         # load value
       
    72         orientation = self.image_tag_value('Orientation')
       
    73 
       
    74         # map to tuple or None
       
    75         # XXX: these are from EXIFpy, verify
       
    76         return {
       
    77             1:  (MIRROR_NONE,       ROTATE_NONE ),  # Horizontal (normal)
       
    78             2:  (MIRROR_HORIZONTAL, ROTATE_NONE ),  # Mirrored horizontal
       
    79             3:  (MIRROR_NONE,       ROTATE_180  ),  # Rotated 180
       
    80             4:  (MIRROR_VERTICAL,   ROTATE_NONE ),  # Mirrored vertical
       
    81             5:  (MIRROR_HORIZONTAL, ROTATE_270  ),  # Mirrored horizontal then rotated 90 CCW
       
    82             6:  (MIRROR_NONE,       ROTATE_90   ),  # Rotated 90 CW
       
    83             7:  (MIRROR_HORIZONTAL, ROTATE_90   ),  # Mirrored horizontal then rotated 90 CW
       
    84             8:  (MIRROR_NONE,       ROTATE_270  ),  # Rotated 90 CCW
       
    85         }.get(orientation, None)
    44 
    86 
    45 try :
    87 try :
    46     import pyexiv2
    88     import pyexiv2
    47 
    89 
    48 except ImportError :
    90 except ImportError :
    61             self.image = pyexiv2.Image(file.path)
   103             self.image = pyexiv2.Image(file.path)
    62 
   104 
    63             # load
   105             # load
    64             self.image.readMetadata()
   106             self.image.readMetadata()
    65         
   107         
       
   108         def image_tag_value (self, tag, default=None) :
       
   109             # try with likely prefixes
       
   110             for prefix in ('Exif.Photo', 'Exif.Image') :
       
   111                 try :
       
   112                     return self.image["%s.%s" % (prefix, tag)]
       
   113                 
       
   114                 except (IndexError, KeyError) :
       
   115                     # nope...
       
   116                     continue
       
   117 
       
   118             else :
       
   119                 # not ofund
       
   120                 return default
       
   121 
    66         def image_tag (self, tag, default=None) :
   122         def image_tag (self, tag, default=None) :
    67             # try with likely prefixes
   123             # try with likely prefixes
    68             for prefix in ('Exif.Photo', 'Exif.Image') :
   124             for prefix in ('Exif.Photo', 'Exif.Image') :
    69                 try :
   125                 try :
    70                     return self.image.interpretedExifValue("%s.%s" % (prefix, tag))
   126                     return self.image.interpretedExifValue("%s.%s" % (prefix, tag))