[Tutor] Obtaining image date of creation

Scott SA pydev at rscorp.ab.ca
Thu Nov 15 06:24:48 CET 2007


On 11/14/07, Roy Chen (roychenlei at gmail.com) wrote:

>I would like to write a simple script that would rename a bunch of  
>photos according to their creation date, i.e. the date which the  
>photo was taken.
>
>Is there a way to use Python to obtain that information from the  
>image file, or is that information not stored in the file?

There are a couple of EXIF libraries dedicated to reading EXIF headers of JPEG images plus, as mentioned by others PIL. Another great imaging library is ImageMagick but last time I looked the wrapper for it was in disarray IIRC.

A really quick snoop 'round the web turned up this PIL snippet:

    from PIL import Image
    from PIL.ExifTags import TAGS
    
    def get_exif(fn):
        ret = {}
        i = Image.open(fn)
        info = i._getexif()
        for tag, value in info.items():
            decoded = TAGS.get(tag, tag)
            ret[decoded] = value
        return ret

Posted by 'Justin' here:
    <http://wolfram.kriesing.de/blog/index.php/2006/reading-out-exif-data-via-python>


There is also:
    <http://pyexif.sourceforge.net/> (recommends EXIF.py below)
    <http://www.emilas.com/jpeg/>
    <http://www.imagemagick.org> (py-magic is one library-wrapper)

EXIF.py is a possible choice for this task:
    <http://sourceforge.net/projects/exif-py>

Here's a sample of what I did to extract the tags I was interested in (I wanted _more_ than the dates ;-). I also wanted something that could handle the variances between manufacturers i.e. not using a particular tag. There _are_ tags missing in EXIF.py although it has been updated recently for some Nikon and Olympus stuff.

This is a portion of a class I wrote to wrap other tasks, I didn't do anything wonderful here with exception handling:

    import EXIF
    
    def fetch_exif(strPath):
        
        # dictionary of desired tags (I have it elsewhere in the class). 
        # Only one of a few ways to do this...
        exif_tags = {
            'EXIF DateTimeDigitized': '',
            'EXIF DateTimeOriginal': '',
            'EXIF ExifImageLength': '',
            'EXIF ExifImageWidth': '',
            'EXIF ExifVersion': '',
            'EXIF ExposureBiasValue': '',
            'EXIF ExposureProgram': '',
            'EXIF ExposureTime': '',
            'EXIF Flash': '',
            'EXIF FNumber': '',
            'EXIF FocalLength': '',
            'EXIF ISOSpeedRatings': '',
            'EXIF MaxApertureValue': '',
            'EXIF MeteringMode': '',
            'EXIF SceneType': '',
            'EXIF ShutterSpeedValue': '',
            'EXIF SubSecTime': '',
            'Image DateTime': '',
            'Image ImageDescription': '',
            'Image Make': '',
            'Image Model': '',
            'Image Orientation': '',
            'Image XResolution': '',
            'Image YResolution': '',
            'ImageType': '',
            'ImageNumber': '',
            'OwnerName': '',
            'SerialNumber': '',
            'FirmwareVersion': '',
            'InternalSerialNumber': '',
            }

        exif_keys = exif_tags.keys()
        
        # iterate the keys looking for desirable/desired tags
        try:
            image_file = open(strPath,'rb')
            image_tags = EXIF.process_file(image_file, details=False)
            image_file.close()
            image_keys = image_tags.keys()
            
            for key_name in exif_keys:
                if key_name in image_keys:
                    exif_tags[key_name] = image_tags[key_name]
            
        except:
            # typically caused by missing exif
            exif_tags = False
            image_file.close()
            
        return exif_tags


A more compact option would have been to iterate a simple list of _desired_ tags, then build the dictionary of the ones available.
    
    return_exif_dict = {}
    
    shopping_list = ['EXIF DateTimeDigitized', 'EXIF DateTimeOriginal', 
    'EXIF ExifImageLength', 'EXIF ExifImageWidth', 'EXIF ExifVersion', 
    'EXIF ExposureBiasValue', 'EXIF ExposureProgram', 'EXIF ExposureTime', 
    'EXIF Flash', 'EXIF FNumber', 'EXIF FocalLength', 'EXIF ISOSpeedRatings',       
    'EXIF MaxApertureValue', 'EXIF MeteringMode', 'EXIF SceneType', 
    'EXIF ShutterSpeedValue', 'EXIF SubSecTime', 'Image DateTime', 
    'Image ImageDescription', 'Image Make', 'Image Model', 
    'Image Orientation', 'Image XResolution', 'Image YResolution', 
    'ImageType', 'ImageNumber', 'OwnerName', 'SerialNumber', 
    'FirmwareVersion', 'InternalSerialNumber'] 
    
    try:
        image_file = open(strPath,'rb')
        image_tags = EXIF.process_file(image_file, details=False)
        image_file.close()
        image_keys = image_tags.keys()

        for key_name in exif_keys:
        if key_name in image_keys:
            return_exif_dict[key_name] = image_tags[key_name]
    ...


You should be aware that it _is_ possible for a DC to take more than one image per second - though with a consumer P&S it is unlikely. The solution I used was to capture the camera's original sequential number - had the added benefit of letting the photogs I was working with reference to their own libraries later.

There are lots of pages to be found discussing file renaming and date conversions, so that should not be a problem... just be sure to use file-system compatible characters (sorry, I don't know your python exp. - just covering a couple of bases).

HTH

Scott


More information about the Tutor mailing list