diff options
-rw-r--r-- | src/pyexiv2.py | 127 |
1 files changed, 103 insertions, 24 deletions
diff --git a/src/pyexiv2.py b/src/pyexiv2.py index a7e0fb1..79fe6ca 100644 --- a/src/pyexiv2.py +++ b/src/pyexiv2.py @@ -25,38 +25,104 @@ # File: pyexiv2.py # Author(s): Olivier Tilloy <olivier@tilloy.net> # History: 28-Dec-06, Olivier Tilloy: created +# 30-Dec-06, Olivier Tilloy: documentation using doc strings # # ****************************************************************************** +""" +Manipulation of EXIF and IPTC metadata embedded in image files. + +This module provides a single class, Image, and utility functions to manipulate +EXIF and IPTC metadata embedded in image files such as JPEG and TIFF files. +EXIF and IPTC metadata can be accessed in both read and write modes. + +This module is a higher-level interface to the Python binding of the excellent +C++ library Exiv2, libpyexiv2. +Its only class, Image, inherits from libpyexiv2.Image and provides convenient +methods for the manipulation of EXIF and IPTC metadata using Python's built-in +types and modules such as datetime. +These methods should be preferred to the ones directly provided by +libpyexiv2.Image. + +A typical use of this binding is as follows: + + import pyexiv2 + import datetime + image = pyexiv2.Image('path/to/imagefile') + image.readMetadata() + print image.getAvailableExifTags() + print image.getExifTagValue('Exif.Photo.DateTimeOriginal') + today = datetime.datetime.today() + image.setExifTagValue('Exif.Photo.DateTimeOriginal', today) + image.writeMetadata() + ... + +""" + import libpyexiv2 import re import datetime def UndefinedToString(undefined): - # undefined must be a string containing the ascii codes of a sequence of - # bytes, each followed by a blank space (e.g. "48 50 50 49 " for "0221") + """ + Convert an undefined string into its corresponding sequence of bytes. + + Convert a string containing the ascii codes of a sequence of bytes, each + followed by a blank space, into the corresponding string (e.g. + "48 50 50 49 " will be converted into "0221"). + The Undefined type is defined in the EXIF specification. + + Keyword arguments: + undefined -- the string containing the ascii codes of a sequence of bytes + """ return ''.join(map(lambda x: chr(int(x)), undefined.rstrip().split(' '))) -def StringToUndefined(string): - # string must be a string containing a sequence of ascii representations - # of bytes, to be converted in the suitable format for the type - # 'Undefined' in EXIF specification (e.g. "0221" will be converted into - # "48 50 50 49 ") - return ''.join(map(lambda x: '%d ' % ord(x), string)) +def StringToUndefined(sequence): + """ + Convert a string containing a sequence of bytes into its undefined form. + + Convert a string containing a sequence of bytes into the corresponding + sequence of ascii codes, each followed by a blank space (e.g. "0221" will + be converted into "48 50 50 49 "). + The Undefined type is defined in the EXIF specification. + + Keyword arguments: + sequence -- the string containing the sequence of bytes + """ + return ''.join(map(lambda x: '%d ' % ord(x), sequence)) class Image(libpyexiv2.Image): + """ - A class that extends the methods of class libpyexiv2.Image with "higher - level methods", making use of Python's built-in types and classes such as - datetime. + Provide convenient methods for the manipulation of EXIF and IPTC metadata. + + Provide convenient methods for the manipulation of EXIF and IPTC metadata + embedded in image files such as JPEG and TIFF files, using Python's built-in + types and modules such as datetime. + + Public methods: + getExifTagValue -- get the value associated to a key in EXIF metadata + setExifTagValue -- set the value associated to a key in EXIF metadata """ + def getExifTagValue(self, key): + """ + Get the value associated to a key in EXIF metadata. + + Get the value associated to a key in EXIF metadata. + Whenever possible, the value is typed using Python's built-in types or + modules such as datetime when the value is composed of a date and a time + (e.g. the EXIF tag 'Exif.Photo.DateTimeOriginal'). + + Keyword arguments: + key -- the EXIF key of the requested metadata tag + """ tagType, tagValue = self.getExifTag(key) if tagType == 'Byte': return tagValue elif tagType == 'Ascii': - # tries to guess if the value is a datetime + # try to guess if the value is a datetime pattern = re.compile("([0-9]{4}):([0-9]{2}):([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})") match = pattern.match(tagValue) if match == None: @@ -87,18 +153,31 @@ class Image(libpyexiv2.Image): v = map(long, match.groups()) return v[0], v[1] elif tagType == 'Undefined': - # tagValue is a sequence of bytes whose codes are written as - # a string, each code being followed by a blank space - # (e.g. "48 50 50 49 " for "0221") - # Note: in the case of tag "Exif.Photo.UserComment", it is - # better to call method getExifTagToString() to obtain - # directly the value as a human-readable string + # tagValue is a sequence of bytes whose codes are written as a + # string, each code being followed by a blank space (e.g. + # "48 50 50 49 " for "0221"). + # Note: in the case of tag "Exif.Photo.UserComment", it is better to + # call method getExifTagToString() to obtain directly the value as a + # human-readable string. return UndefinedToString(tagValue) else: # empty type and value return def setExifTagValue(self, key, value): + """ + Set the value associated to a key in EXIF metadata. + + Set the value associated to a key in EXIF metadata. + The new value passed should be typed using Python's built-in types or + modules such as datetime when the value is composed of a date and a time + (e.g. the EXIF tag 'Exif.Photo.DateTimeOriginal'), the method takes care + of converting it before setting the internal EXIF tag value. + + Keyword arguments: + key -- the EXIF key of the requested metadata tag + value -- the new value for the requested metadata tag + """ valueType = value.__class__ if valueType == int or valueType == long: strVal = str(value) @@ -107,11 +186,11 @@ class Image(libpyexiv2.Image): elif valueType == tuple: strVal = '%s/%s' % (str(value[0]), str(value[1])) else: - # value must already be a string - # warning: no distinction is possible between values that - # really are strings (type 'Ascii') and those that are - # supposed to be sequences of bytes (type 'Undefined'), in - # which case value must be passed as a string correctly - # formatted, using function StringToUndefined() + # Value must already be a string. + # Warning: no distinction is possible between values that really are + # strings (type 'Ascii') and those that are supposed to be sequences + # of bytes (type 'Undefined'), in which case value must be passed as + # a string correctly formatted, using utility function + # StringToUndefined(). strVal = value self.setExifTag(key, strVal) |