xmpsample.cpp

Sample usage of high-level XMP classes.

00001 // ***************************************************************** -*- C++ -*-
00002 // xmpsample.cpp, $Rev: 1305 $
00003 // Sample/test for high level XMP classes. See also addmoddel.cpp
00004 
00005 #include <exiv2/xmp.hpp>
00006 #include <exiv2/error.hpp>
00007 
00008 #include <string>
00009 #include <iostream>
00010 #include <iomanip>
00011 
00012 int main()
00013 try {
00014     // The XMP property container
00015     Exiv2::XmpData xmpData;
00016 
00017     // -------------------------------------------------------------------------
00018     // Teaser: Setting XMP properties doesn't get much easier than this:
00019 
00020     xmpData["Xmp.dc.source"]  = "xmpsample.cpp";    // a simple text value
00021     xmpData["Xmp.dc.subject"] = "Palmtree";         // an array item
00022     xmpData["Xmp.dc.subject"] = "Rubbertree";       // add a 2nd array item
00023     // a language alternative with two entries and without default
00024     xmpData["Xmp.dc.title"]   = "lang=de-DE Sonnenuntergang am Strand";
00025     xmpData["Xmp.dc.title"]   = "lang=en-US Sunset on the beach";
00026 
00027     // -------------------------------------------------------------------------
00028     // Any properties can be set provided the namespace is known. Values of any
00029     // type can be assigned to an Xmpdatum, if they have an output operator. The
00030     // default XMP value type for unknown properties is a simple text value.
00031 
00032     xmpData["Xmp.dc.one"]     = -1;
00033     xmpData["Xmp.dc.two"]     = 3.1415;
00034     xmpData["Xmp.dc.three"]   = Exiv2::Rational(5, 7);
00035     xmpData["Xmp.dc.four"]    = uint16_t(255);
00036     xmpData["Xmp.dc.five"]    = int32_t(256);
00037     xmpData["Xmp.dc.six"]     = false;
00038 
00039     // In addition, there is a dedicated assignment operator for Exiv2::Value
00040     Exiv2::XmpTextValue val("Seven");
00041     xmpData["Xmp.dc.seven"]   = val;
00042 
00043     // -------------------------------------------------------------------------
00044     // Exiv2 has specialized values for simple XMP properties, arrays of simple
00045     // properties and language alternatives.
00046 
00047     // Add a simple XMP property in a known namespace    
00048     Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::xmpText);
00049     v->read("image/jpeg");
00050     xmpData.add(Exiv2::XmpKey("Xmp.dc.format"), v.get());
00051 
00052     // Add an ordered array of text values.
00053     v = Exiv2::Value::create(Exiv2::xmpSeq); // or xmpBag or xmpAlt.
00054     v->read("1) The first creator");         // The sequence in which the array
00055     v->read("2) The second creator");        // elements are added is their
00056     v->read("3) And another one");           // order in the array.
00057     xmpData.add(Exiv2::XmpKey("Xmp.dc.creator"), v.get());
00058 
00059     // Add a language alternative property
00060     v = Exiv2::Value::create(Exiv2::langAlt);
00061     v->read("lang=de-DE Hallo, Welt");       // The default doesn't need a 
00062     v->read("Hello, World");                 // qualifier
00063     xmpData.add(Exiv2::XmpKey("Xmp.dc.description"), v.get());
00064 
00065     // According to the XMP specification, Xmp.tiff.ImageDescription is an
00066     // alias for Xmp.dc.description. Exiv2 treats an alias just like any
00067     // other property and leaves it to the application to implement specific
00068     // behaviour if desired.
00069     xmpData["Xmp.tiff.ImageDescription"] = "TIFF image description";
00070     xmpData["Xmp.tiff.ImageDescription"] = "lang=de-DE TIFF Bildbeschreibung";
00071 
00072     // -------------------------------------------------------------------------
00073     // Register a namespace which Exiv2 doesn't know yet. This is only needed
00074     // when properties are added manually. If the XMP metadata is read from an
00075     // image, namespaces are decoded and registered at the same time.
00076     Exiv2::XmpProperties::registerNs("myNamespace/", "ns");
00077 
00078     // -------------------------------------------------------------------------
00079     // There are no specialized values for structures, qualifiers and nested
00080     // types. However, these can be added by using an XmpTextValue and a path as
00081     // the key.
00082 
00083     // Add a structure
00084     Exiv2::XmpTextValue tv("16");
00085     xmpData.add(Exiv2::XmpKey("Xmp.xmpDM.videoFrameSize/stDim:w"), &tv);
00086     tv.read("9");
00087     xmpData.add(Exiv2::XmpKey("Xmp.xmpDM.videoFrameSize/stDim:h"), &tv);
00088     tv.read("inch");
00089     xmpData.add(Exiv2::XmpKey("Xmp.xmpDM.videoFrameSize/stDim:unit"), &tv);
00090 
00091     // Add an element with a qualifier (using the namespace registered above)
00092     xmpData["Xmp.dc.publisher"] = "James Bond";  // creates an unordered array
00093     xmpData["Xmp.dc.publisher[1]/?ns:role"] = "secret agent";
00094 
00095     // Add a qualifer to an array element of Xmp.dc.creator (added above)
00096     tv.read("programmer");
00097     xmpData.add(Exiv2::XmpKey("Xmp.dc.creator[2]/?ns:role"), &tv);
00098 
00099     // Add an array of structures
00100     tv.read("");                                         // Clear the value
00101     tv.setXmpArrayType(Exiv2::XmpValue::xaBag);
00102     xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef"), &tv); // Set the array type.
00103 
00104     tv.setXmpArrayType(Exiv2::XmpValue::xaNone);
00105     tv.read("Birthday party");
00106     xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef[1]/stJob:name"), &tv);
00107     tv.read("Photographer");
00108     xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef[1]/stJob:role"), &tv);
00109 
00110     tv.read("Wedding ceremony");
00111     xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef[2]/stJob:name"), &tv);
00112     tv.read("Best man");
00113     xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef[2]/stJob:role"), &tv);
00114 
00115     // -------------------------------------------------------------------------
00116     // Output XMP properties
00117     for (Exiv2::XmpData::const_iterator md = xmpData.begin(); 
00118          md != xmpData.end(); ++md) {
00119         std::cout << std::setfill(' ') << std::left
00120                   << std::setw(44)
00121                   << md->key() << " "
00122                   << std::setw(9) << std::setfill(' ') << std::left
00123                   << md->typeName() << " "
00124                   << std::dec << std::setw(3)
00125                   << std::setfill(' ') << std::right
00126                   << md->count() << "  "
00127                   << std::dec << md->value()
00128                   << std::endl;
00129     }
00130 
00131     // -------------------------------------------------------------------------
00132     // Serialize the XMP data and output the XMP packet
00133     std::string xmpPacket;
00134     if (0 != Exiv2::XmpParser::encode(xmpPacket, xmpData)) {
00135         throw Exiv2::Error(1, "Failed to serialize XMP data");
00136     }
00137     std::cout << xmpPacket << "\n";
00138 
00139     // Cleanup
00140     Exiv2::XmpParser::terminate();
00141 
00142     return 0;
00143 }
00144 catch (Exiv2::AnyError& e) {
00145     std::cout << "Caught Exiv2 exception '" << e << "'\n";
00146     return -1;
00147 }

Generated on Sat Mar 1 08:38:15 2008 for Exiv2 by  doxygen 1.5.1