How can I add structures?

Asked by Philipp Brimmers on 2012-01-13

I tried to add structures, but it don't work. It is possible to add them?
I use pyexiv 3.2 binaries for Windows (32 bit) with Python 2.7 and Windows 7.

Here is my code:
from __future__ import print_function, unicode_literals
import pyexiv2

def write_test():
    m = pyexiv2.ImageMetadata("test-no_metadata.jpg")
    m.read()
    print('Initial XMP-Tags: ' + repr(m.xmp_keys))
    register_namespace("foo/", "foo")
    m[str('Xmp.foo.bar/bla')] = pyexiv2.XmpTag(str('Xmp.foo.bar/bla'), str('Buh'))
    m[str('Xmp.xmpDM.videoFrameSize/stDim:w')] = pyexiv2.XmpTag(str('Xmp.xmpDM.videoFrameSize/stDim:w'), str('16'))
    m[str('Xmp.foo.bar/foo:bla')] = pyexiv2.XmpTag(str('Xmp.foo.bar/foo:bla'), str('Buh'))
    print('Add some tags: ' + repr(m.xmp_keys))
    m.write()
    m = pyexiv2.ImageMetadata("test-no_metadata.jpg")
    m.read()
    print('Write and then read tags: ' + repr(m.xmp_keys))

if __name__ == '__main__':
    write_test()

Output:
Initial XMP-Tags: ['Xmp.xmp.Label', 'Xmp.foo.bar']
Add some tags: ['Xmp.xmp.Label', 'Xmp.foo.bar', 'Xmp.foo.bar/bla', 'Xmp.xmpDM.videoFrameSize/stDim:w', 'Xmp.foo.bar/foo:bla']
Write and then read tags: ['Xmp.xmp.Label', 'Xmp.foo.bar']

Exiv2 supports writing structures as shown in this example:
http://www.exiv2.org/doc/xmpsample_8cpp-example.html

Question information

Language:
English Edit question
Status:
Answered
For:
pyexiv2 Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Philipp Brimmers (p-brimmers) said : #1

It is possible to write in an existing structure. Like this:

def write_test2():
    m = pyexiv2.ImageMetadata("test.tif")
    m.read()
    m[str('Xmp.BIGS.Lighting/lighting:Color')] = str('Red (630 nm)')
    m.write()
    m = pyexiv2.ImageMetadata("test.tif")
    m.read()
    print('Xmp.BIGS.Lighting/lighting:Color: ' + str(m[str('Xmp.BIGS.Lighting/lighting:Color')].value))

Value before executing the function:
White (6500° K)

Output:
Xmp.BIGS.Lighting/lighting:Color: Red (630 nm)

Olivier Tilloy (osomon) said : #2

Writing structures to known tags works as expected, see the following example:

    import pyexiv2
    m=pyexiv2.ImageMetadata('test/data/smiley1.jpg')
    m.read()
    m['Xmp.xmpDM.videoFrameSize/stDim:w'] = '16'
    m['Xmp.xmpDM.videoFrameSize/stDim:h'] = '9'
    m['Xmp.xmpDM.videoFrameSize/stDim:unit'] = 'inch'
    m.write()

This is the output of `exiv2 -PXkyv test/data/smiley1.jpg` afterwards:

    Xmp.xmpDM.videoFrameSize XmpText type="Struct"
    Xmp.xmpDM.videoFrameSize/stDim:w XmpText 16
    Xmp.xmpDM.videoFrameSize/stDim:h XmpText 9
    Xmp.xmpDM.videoFrameSize/stDim:unit XmpText inch

Note that before that the image didn’t have any XMP metadata.

However writing structures to unknown tags in custom namespaces (e.g. 'Xmp.foo.bar/bla') won’t work indeed. This is a limitation of the current version that might be removed in the future.

Philipp Brimmers (p-brimmers) said : #3

Hey Olivier,

thanks for the answer, but my main goal is to write structures and bags in a custom namespace.
I can't register it in the exiv2 code as described in the forum (http://dev.exiv2.org/boards/3/topics/1039),
because i want to write arbitrary namespaces which are defined in an extern schema, and not in python code.
Why is this limit? Can I help to fix it? Is this a problem which can be solved by editing the python code?
Or is it necessary to change the c++ code as well?

Olivier Tilloy (osomon) said : #4

Sorry for the delay in answering…

I haven’t looked into it in details, but you’d almost certainly need to go into the C++ part of the binding. Contributions are very welcome and I can help answering questions you may have if you chose to give it a shot.

I’m afraid the problem is architectural: when assigning a value to an unknown tag, pyexiv2, unlike libexiv2, doesn’t allow you to chose the type of the value; instead it queries libexiv2 for this information, and since the tag is unknown, the default value, XmpText, is returned.
Changing this behaviour would require an additional API to allow setting the type of a tag’s value explicitly. This sounds like quite an invasive change. It’s not that it can’t be done, but it most certainly requires quite some thinking and work.

Philipp Brimmers (p-brimmers) said : #5

Ok ,thanks for answering. That is too much work for me.
I will use exiftool to write the tags once and then I can use pyexiv2.

I hope the feature will be available in future.

Can you help with this problem?

Provide an answer of your own, or ask Philipp Brimmers for more information if necessary.

To post a message you must log in.