Exiv2 programatically add custom property
Added by Ladislav Kopecky over 4 years ago
Hi,
I am starting with Exiv2 library with C++.
Is there any way how add custom namespace and XMP property to Exiv2 with C++ source code?
I found only this way how add new namespace to Exiv2. It is working.
Exiv2::XmpProperties::registerNs("http://customNamespace.com/", "cn");
xmpData["Xmp.cn.foo"] = "boo";
But when I want use this to create array serialization it finish with error: Failed to serialize XMP data
// Add an array of structures
Exiv2::XmpTextValue tv("");
tv.setXmpArrayType(Exiv2::XmpValue::xaSeq);
xmpData.add(Exiv2::XmpKey("Xmp.cn.foo"), &tv); // Set the array type.
tv.setXmpArrayType(Exiv2::XmpValue::xaNone);
tv.read("Birthday party");
xmpData.add(Exiv2::XmpKey("Xmp.cn.foo[1]/stRef:open"), &tv);
It is here some way how to create array serialization with custom property?
Thank you
Ladislav
Replies (1)
RE: Exiv2 programatically add custom property - Added by Robin Mills over 4 years ago
Ladislav
I had this conversation (by email) with a user last week!
Robin
On 22 May 2017, at 20:25, P M <pm@xxxxxxx.com> wrote: hi Robin, I am trying to integrate Exiv2 with our software, and running into an exception doing things like xmpData["Xmp.Camera.RigName"] = "1234ABCD5678"; Likewise, attempts to set some other common XMP entries lead to the same result: xmpData["Xmp.Camera.SerialNumber"] = 12345678; There's a file xmpsample.cpp with something very similar to this; what am I doing wrong? In addition, I tried to follow xmpData.add(Exiv2::XmpKey(...), v.get()); routine - just to run into compiler errors. Are these XMP tags declared someplace, along with "prescribed" data types and methods? Thank you,
My Response¶
I’m not a Metadata expert. I’m a retired Software Engineer. I know a lot about the Exiv2 code. I know very little about the meaning of the metadata or how various keys and values should be used.
Exiv2 has a predefined set of 69 namespaces which you can discover with the command:
529 rmills@rmillsmbp:~/gnu/git/exiv2/test/data $ exiv2 exiv2 --verbose --version --grep xmlns exiv2 0.26 001a00 (64 bit build) xmlns=DICOM:http://ns.adobe.com/DICOM/ xmlns=GPano:http://ns.google.com/photos/1.0/panorama/ …
They are documented here: http://www.exiv2.org/metadata.html
If you want to add a namespace such as “Camera” you have to register it:
532 rmills@rmillsmbp:~/gnu/git/exiv2/test/data $ exiv2 -M'reg Camera http://clanmills.com/ns/Camera' -M'set Xmp.Camera.Make "123456789"' ~/Stonehenge.jpg
Once the namespace is in your file, you don’t need to register it again to read data.
533 rmills@rmillsmbp:~/gnu/git/exiv2/test/data $ exiv2 -pa —grep Camera ~/Stonehenge.jpg Xmp.Camera.Make XmpText 9 123456789 533 rmills@rmillsmbp:~/gnu/git/exiv2/test/data $
However, you do have to register it to write another key:
538 rmills@rmillsmbp:~/gnu/git/exiv2/test/data $ exiv2 -M'reg Camera http://clanmills.com/ns/Camera' -M'set Xmp.Camera.BodyColor Black' ~/Stonehenge.jpg 539 rmills@rmillsmbp:~/gnu/git/exiv2/test/data $ exiv2 -px --grep Camera ~/Stonehenge.jpg Xmp.Camera.Make XmpText 9 123456789 Xmp.Camera.BodyColor XmpText 5 Black
You can change the URI associated with a namespace:
540 rmills@rmillsmbp:~/gnu/git/exiv2/test/data $ exiv2 -M'reg Camera http://clanmills.com/ns/Camora' -M'set Xmp.Camera.BodyColor Black' ~/Stonehenge.jpg Warning: Updating namespace URI for Camera from http://clanmills.com/ns/Camera/ to http://clanmills.com/ns/Camora/ 541 rmills@rmillsmbp:~/gnu/git/exiv2/test/data $
In general, Exiv2 XMP support is a veneer over the Adobe XMPsdk. We neither add a metadata policeman, nor disable checks performed by Adobe. It appears to me that you can add any key to a namespace, even when it’s not mentioned in the spec. So, the “Dublin Core” namespace is documented here http://www.exiv2.org/tags-xmp-dc.html You can add keys which are not mentioned in the specification.
534 rmills@rmillsmbp:~/gnu/git/exiv2/test/data $ exiv2 -M'set Xmp.dc.Today "Tuesday"' ~/Stonehenge.jpg 535 rmills@rmillsmbp:~/gnu/git/exiv2/test/data $ exiv2 -px --grep Today ~/Stonehenge.jpg Xmp.dc.Today XmpText 7 Tuesday 536 rmills@rmillsmbp:~/gnu/git/exiv2/test/data $
You should be able to figure out the APIs being used by the exiv2(.exe) application from the documentation. In general, almost everything in the library can be exercised from the exiv2(.exe) command-line program and you can build/debug that to see what’s going on.
For example, the command to register a namespace is implemented in src/actions.cpp as:
void Modify::regNamespace(const ModifyCmd& modifyCmd) { if (Params::instance().verbose_) { std::cout << _("Reg ") << modifyCmd.key_ << "=\"" << modifyCmd.value_ << "\"" << std::endl; } Exiv2::XmpProperties::registerNs(modifyCmd.value_, modifyCmd.key_); }
547 rmills@rmillsmbp:~/gnu/git/exiv2/src $ exiv2 --verbose -M'reg Camera http://clanmills.com/ns/Comora' -M'set Xmp.Camera.BodyColor Black' ~/Stonehenge.jpg File 1/1: /Users/rmills/Stonehenge.jpg Reg Camera="http://clanmills.com/ns/Comora" Warning: Updating namespace URI for Camera from http://clanmills.com/ns/Camora/ to http://clanmills.com/ns/Comora/ Set Xmp.Camera.BodyColor "Black" (XmpText) 548 rmills@rmillsmbp:~/gnu/git/exiv2/src $
Exiv2::XmpProperties::registerNs is documented here: http://www.exiv2.org/doc/classExiv2_1_1XmpProperties.html
You can query the Xmp data in an image with this command:
551 rmills@rmillsmbp:~/gnu/git/exiv2/src $ exiv2 -px ~/Stonehenge.jpg Xmp.xmp.Rating XmpText 9 123456789 Xmp.xmp.ModifyDate XmpText 25 2015-07-16T20:25:28+01:00 Xmp.Camera.Make XmpText 9 123456789 Xmp.Camera.BodyColor XmpText 5 Black Xmp.dc.Today XmpText 7 Tuesday Xmp.dc.description LangAlt 1 lang="x-default" Classic View
And dump the raw XMP/xml as follows:
552 rmills@rmillsmbp:~/gnu/git/exiv2/src $ exiv2 -pX ~/Stonehenge.jpg | xmllint --format - <?xml version="1.0"?> <?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:Camera="http://clanmills.com/ns/Comora/" xmlns:dc="http://purl.org/dc/elements/1.1/" rdf:about="" xmp:Rating="123456789" xmp:ModifyDate="2015-07-16T20:25:28+01:00" Camera:Make="123456789" Camera:BodyColor="Black" dc:Today="Tuesday"> <dc:description> <rdf:Alt> <rdf:li xml:lang="x-default">Classic View</rdf:li> </rdf:Alt> </dc:description> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="w"?> 553 rmills@rmillsmbp:~/gnu/git/exiv2/src $
I hope that helps.
Robin