Writing complex custom metadata on images through python
Question: I'm looking to write custom metadata on to images(mostly jpegs, but could be
others too). So far I haven't been able to do that through PIL preferably (I'm
on centos 5 & I couldn't get pyexiv installed) I understand that I can update
some pre-defined tags, but I need to create custom fields/tags! Can that be
done?

This data would be created by users, so I wouldn't know what those tags are
before hand or what they contain. I need to allow them to create tags/subtags
& then write data for them. For example, someone may want to create this
metadata on a particular image :

    
    
    Category : Human
    
    Physical :
        skin_type : smooth
        complexion : fair
        eye_color: blue
        beard: yes
        beard_color: brown
        age: mid
    
    Location :
        city: london
        terrain: grass
        buildings: old
    

I also found that upon saving a jpeg through the PIL JpegImagePlugin, all
previous metadata is overwritten with new data that you don't get to edit? Is
that a bug?

Cheers, S


Answer: The python [pyexiv2 module](http://tilloy.net/dev/pyexiv2/api.html) can
read/write metadata.

I think there is a limited set of valid EXIF tags. I don't know how, or if it
is possible to create your own custom tags. However, you could use the
Exif.Photo.UserComment tag, and fill it with JSON:

    
    
    import pyexiv2
    import json
    
    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()
    userdata={'Category':'Human',
              'Physical': {
                  'skin_type':'smooth',
                  'complexion':'fair'
                  },
              'Location': {
                  'city': 'london'
                  }
              }
    metadata['Exif.Photo.UserComment']=json.dumps(userdata)
    metadata.write()
    

And to read it back:

    
    
    import pprint
    filename='/tmp/image.jpg'
    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()
    userdata=json.loads(metadata['Exif.Photo.UserComment'].value)
    pprint.pprint(userdata)
    

yields

    
    
    {u'Category': u'Human',
     u'Location': {u'city': u'london'},
     u'Physical': {u'complexion': u'fair', u'skin_type': u'smooth'}}
    

