diff --git a/website/doxygen/intro.html b/website/doxygen/intro.html index fc1ee77a..a0b74b7f 100644 --- a/website/doxygen/intro.html +++ b/website/doxygen/intro.html @@ -82,18 +82,18 @@ provided to simplify the use of XMP properties. Note: Unlike Exif and IPTC tags, XMP properties do not have a tag number. -
There are several simple examples that demonstrate the basic use of Exiv2
-functionality: Exifprint
+functionality: Exifprint
shows how the Exif data of an image can be read and written to the screen.
-Iptcprint is a similar
+Iptcprint is a similar
example to print IPTC data.
-Addmoddel shows how to
+Addmoddel shows how to
add, modify and delete Exif metadata.
Exifcomment shows how to
set the exif comment of an image.
-Xmpsample.cpp contains examples
+Xmpsample.cpp contains examples
of how to set various types of XMP properties.
For more real-world code have a look at the implementation of the
diff --git a/website/master/examples.html.in b/website/master/examples.html.in
index 452d7833..5fea7ac1 100644
--- a/website/master/examples.html.in
+++ b/website/master/examples.html.in
@@ -1,6 +1,7 @@
__doctype__
__header4__
+
// ***************************************************************** -*- C++ -*- -// exifprint.cpp, $Rev: 2286 $ -// Sample program to print the Exif metadata of an image - -#include <exiv2/exiv2.hpp> -#include <iostream> -#include <iomanip> -#include <cassert> - -int main(int argc, char* const argv[]) -try { - - if (argc != 2) { - std::cout << "Usage: " << argv[0] << " file\n"; - return 1; - } - - Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]); - assert(image.get() != 0); - image->readMetadata(); - - Exiv2::ExifData &exifData = image->exifData(); - if (exifData.empty()) { - std::string error(argv[1]); - error += ": No Exif data found in the file"; - throw Exiv2::Error(1, error); - } - Exiv2::ExifData::const_iterator end = exifData.end(); - for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) { - const char* tn = i->typeName(); - std::cout << std::setw(44) << std::setfill(' ') << std::left - << i->key() << " " - << "0x" << std::setw(4) << std::setfill('0') << std::right - << std::hex << i->tag() << " " - << std::setw(9) << std::setfill(' ') << std::left - << (tn ? tn : "Unknown") << " " - << std::dec << std::setw(3) - << std::setfill(' ') << std::right - << i->count() << " " - << std::dec << i->value() - << "\n"; - } - - return 0; -} -catch (Exiv2::AnyError& e) { - std::cout << "Caught Exiv2 exception '" << e.what() << "'\n"; - return -1; -} -
// ***************************************************************** -*- C++ -*- -// addmoddel.cpp, $Rev: 2286 $ -// Sample program showing how to add, modify and delete Exif metadata. - -#include <exiv2/exiv2.hpp> -#include <iostream> -#include <iomanip> -#include <cassert> - -int main(int argc, char* const argv[]) -try { - if (argc != 2) { - std::cout << "Usage: " << argv[0] << " file\n"; - return 1; - } - std::string file(argv[1]); - - // Container for exif metadata. This is an example of creating - // exif metadata from scratch. If you want to add, modify, delete - // metadata that exists in an image, start with ImageFactory::open - Exiv2::ExifData exifData; - - // ************************************************************************* - // Add to the Exif data - - // This is the quickest way to add (simple) Exif data. If a metadatum for - // a given key already exists, its value is overwritten. Otherwise a new - // tag is added. - exifData["Exif.Image.Model"] = "Test 1"; // AsciiValue - exifData["Exif.Image.SamplesPerPixel"] = uint16_t(162); // UShortValue - exifData["Exif.Image.XResolution"] = int32_t(-2); // LongValue - exifData["Exif.Image.YResolution"] = Exiv2::Rational(-2, 3); // RationalValue - std::cout << "Added a few tags the quick way.\n"; - - // Create a ASCII string value (note the use of create) - Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::asciiString); - // Set the value to a string - v->read("1999:12:31 23:59:59"); - // Add the value together with its key to the Exif data container - Exiv2::ExifKey key("Exif.Photo.DateTimeOriginal"); - exifData.add(key, v.get()); - std::cout << "Added key \"" << key << "\", value \"" << *v << "\"\n"; - - // Now create a more interesting value (without using the create method) - Exiv2::URationalValue::AutoPtr rv(new Exiv2::URationalValue); - // Set two rational components from a string - rv->read("1/2 1/3"); - // Add more elements through the extended interface of rational value - rv->value_.push_back(std::make_pair(2,3)); - rv->value_.push_back(std::make_pair(3,4)); - // Add the key and value pair to the Exif data - key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities"); - exifData.add(key, rv.get()); - std::cout << "Added key \"" << key << "\", value \"" << *rv << "\"\n"; - - // ************************************************************************* - // Modify Exif data - - // Since we know that the metadatum exists (or we don't mind creating a new - // tag if it doesn't), we can simply do this: - Exiv2::Exifdatum& tag = exifData["Exif.Photo.DateTimeOriginal"]; - std::string date = tag.toString(); - date.replace(0, 4, "2000"); - tag.setValue(date); - std::cout << "Modified key \"" << key - << "\", new value \"" << tag.value() << "\"\n"; - - // Alternatively, we can use findKey() - key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities"); - Exiv2::ExifData::iterator pos = exifData.findKey(key); - if (pos == exifData.end()) throw Exiv2::Error(1, "Key not found"); - // Get a pointer to a copy of the value - v = pos->getValue(); - // Downcast the Value pointer to its actual type - Exiv2::URationalValue* prv = dynamic_cast<Exiv2::URationalValue*>(v.release()); - if (prv == 0) throw Exiv2::Error(1, "Downcast failed"); - rv = Exiv2::URationalValue::AutoPtr(prv); - // Modify the value directly through the interface of URationalValue - rv->value_[2] = std::make_pair(88,77); - // Copy the modified value back to the metadatum - pos->setValue(rv.get()); - std::cout << "Modified key \"" << key - << "\", new value \"" << pos->value() << "\"\n"; - - // ************************************************************************* - // Delete metadata from the Exif data container - - // Delete the metadatum at iterator position pos - key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities"); - pos = exifData.findKey(key); - if (pos == exifData.end()) throw Exiv2::Error(1, "Key not found"); - exifData.erase(pos); - std::cout << "Deleted key \"" << key << "\"\n"; - - // ************************************************************************* - // Finally, write the remaining Exif data to the image file - Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(file); - assert(image.get() != 0); - - image->setExifData(exifData); - image->writeMetadata(); - - return 0; -} -catch (Exiv2::AnyError& e) { - std::cout << "Caught Exiv2 exception '" << e << "'\n"; - return -1; -} -
// ***************************************************************** -*- C++ -*- -// iptcprint.cpp, $Rev: 2286 $ -// Sample program to print the IPTC metadata of an image - -#include <exiv2/exiv2.hpp> -#include <iostream> -#include <iomanip> -#include <cassert> - -int main(int argc, char* const argv[]) -try { - - if (argc != 2) { - std::cout << "Usage: " << argv[0] << " file\n"; - return 1; - } - - Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]); - assert (image.get() != 0); - image->readMetadata(); - - Exiv2::IptcData &iptcData = image->iptcData(); - if (iptcData.empty()) { - std::string error(argv[1]); - error += ": No IPTC data found in the file"; - throw Exiv2::Error(1, error); - } - - Exiv2::IptcData::iterator end = iptcData.end(); - for (Exiv2::IptcData::iterator md = iptcData.begin(); md != end; ++md) { - std::cout << std::setw(44) << std::setfill(' ') << std::left - << md->key() << " " - << "0x" << std::setw(4) << std::setfill('0') << std::right - << std::hex << md->tag() << " " - << std::setw(9) << std::setfill(' ') << std::left - << md->typeName() << " " - << std::dec << std::setw(3) - << std::setfill(' ') << std::right - << md->count() << " " - << std::dec << md->value() - << std::endl; - } - - return 0; -} -catch (Exiv2::AnyError& e) { - std::cout << "Caught Exiv2 exception '" << e << "'\n"; - return -1; -} -
// ***************************************************************** -*- C++ -*- -// iptceasy.cpp, $Rev: 2286 $ -// The quickest way to access, set or modify IPTC metadata. - -#include <exiv2/exiv2.hpp> -#include <iostream> -#include <iomanip> -#include <cassert> - -int main(int argc, char* const argv[]) -try { - if (argc != 2) { - std::cout << "Usage: " << argv[0] << " file\n"; - return 1; - } - std::string file(argv[1]); - - Exiv2::IptcData iptcData; - - iptcData["Iptc.Application2.Headline"] = "The headline I am"; - iptcData["Iptc.Application2.Keywords"] = "Yet another keyword"; - iptcData["Iptc.Application2.DateCreated"] = "2004-8-3"; - iptcData["Iptc.Application2.Urgency"] = uint16_t(1); - iptcData["Iptc.Envelope.ModelVersion"] = 42; - iptcData["Iptc.Envelope.TimeSent"] = "14:41:0-05:00"; - iptcData["Iptc.Application2.RasterizedCaption"] = "230 42 34 2 90 84 23 146"; - iptcData["Iptc.0x0009.0x0001"] = "Who am I?"; - - Exiv2::StringValue value; - value.read("very!"); - iptcData["Iptc.Application2.Urgency"] = value; - - std::cout << "Time sent: " << iptcData["Iptc.Envelope.TimeSent"] << "\n"; - - // Open image file - Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(file); - assert (image.get() != 0); - - // Set IPTC data and write it to the file - image->setIptcData(iptcData); - image->writeMetadata(); - - return 0; -} -catch (Exiv2::AnyError& e) { - std::cout << "Caught Exiv2 exception '" << e << "'\n"; - return -1; -} -
// ***************************************************************** -*- C++ -*- -// xmpsample.cpp, $Rev: 1305+edit $ -// Sample/test for high level XMP classes. See also addmoddel.cpp - -#include <exiv2/exiv2.hpp> - -#include <string> -#include <iostream> -#include <iomanip> - -int main() -try { - // The XMP property container - Exiv2::XmpData xmpData; - - // ------------------------------------------------------------------------- - // Teaser: Setting XMP properties doesn't get much easier than this: - - xmpData["Xmp.dc.source"] = "xmpsample.cpp"; // a simple text value - xmpData["Xmp.dc.subject"] = "Palmtree"; // an array item - xmpData["Xmp.dc.subject"] = "Rubbertree"; // add a 2nd array item - // a language alternative with two entries and without default - xmpData["Xmp.dc.title"] = "lang=de-DE Sonnenuntergang am Strand"; - xmpData["Xmp.dc.title"] = "lang=en-US Sunset on the beach"; - - // ------------------------------------------------------------------------- - // Any properties can be set provided the namespace is known. Values of any - // type can be assigned to an Xmpdatum, if they have an output operator. The - // default XMP value type for unknown properties is a simple text value. - - xmpData["Xmp.dc.one"] = -1; - xmpData["Xmp.dc.two"] = 3.1415; - xmpData["Xmp.dc.three"] = Exiv2::Rational(5, 7); - xmpData["Xmp.dc.four"] = uint16_t(255); - xmpData["Xmp.dc.five"] = int32_t(256); - xmpData["Xmp.dc.six"] = false; - - // In addition, there is a dedicated assignment operator for Exiv2::Value - Exiv2::XmpTextValue val("Seven"); - xmpData["Xmp.dc.seven"] = val; - - // ------------------------------------------------------------------------- - // Exiv2 has specialized values for simple XMP properties, arrays of simple - // properties and language alternatives. - - // Add a simple XMP property in a known namespace - Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::xmpText); - v->read("image/jpeg"); - xmpData.add(Exiv2::XmpKey("Xmp.dc.format"), v.get()); - - // Add an ordered array of text values. - v = Exiv2::Value::create(Exiv2::xmpSeq); // or xmpBag or xmpAlt. - v->read("1) The first creator"); // The sequence in which the array - v->read("2) The second creator"); // elements are added is their - v->read("3) And another one"); // order in the array. - xmpData.add(Exiv2::XmpKey("Xmp.dc.creator"), v.get()); - - // Add a language alternative property - v = Exiv2::Value::create(Exiv2::langAlt); - v->read("lang=de-DE Hallo, Welt"); // The default doesn't need a - v->read("Hello, World"); // qualifier - xmpData.add(Exiv2::XmpKey("Xmp.dc.description"), v.get()); - - // According to the XMP specification, Xmp.tiff.ImageDescription is an - // alias for Xmp.dc.description. Exiv2 treats an alias just like any - // other property and leaves it to the application to implement specific - // behaviour if desired. - xmpData["Xmp.tiff.ImageDescription"] = "TIFF image description"; - xmpData["Xmp.tiff.ImageDescription"] = "lang=de-DE TIFF Bildbeschreibung"; - - // ------------------------------------------------------------------------- - // Register a namespace which Exiv2 doesn't know yet. This is only needed - // when properties are added manually. If the XMP metadata is read from an - // image, namespaces are decoded and registered at the same time. - Exiv2::XmpProperties::registerNs("myNamespace/", "ns"); - - // ------------------------------------------------------------------------- - // There are no specialized values for structures, qualifiers and nested - // types. However, these can be added by using an XmpTextValue and a path as - // the key. - - // Add a structure - Exiv2::XmpTextValue tv("16"); - xmpData.add(Exiv2::XmpKey("Xmp.xmpDM.videoFrameSize/stDim:w"), &tv); - tv.read("9"); - xmpData.add(Exiv2::XmpKey("Xmp.xmpDM.videoFrameSize/stDim:h"), &tv); - tv.read("inch"); - xmpData.add(Exiv2::XmpKey("Xmp.xmpDM.videoFrameSize/stDim:unit"), &tv); - - // Add an element with a qualifier (using the namespace registered above) - xmpData["Xmp.dc.publisher"] = "James Bond"; // creates an unordered array - xmpData["Xmp.dc.publisher[1]/?ns:role"] = "secret agent"; - - // Add a qualifer to an array element of Xmp.dc.creator (added above) - tv.read("programmer"); - xmpData.add(Exiv2::XmpKey("Xmp.dc.creator[2]/?ns:role"), &tv); - - // Add an array of structures - tv.read(""); // Clear the value - tv.setXmpArrayType(Exiv2::XmpValue::xaBag); - xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef"), &tv); // Set the array type. - - tv.setXmpArrayType(Exiv2::XmpValue::xaNone); - tv.read("Birthday party"); - xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef[1]/stJob:name"), &tv); - tv.read("Photographer"); - xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef[1]/stJob:role"), &tv); - - tv.read("Wedding ceremony"); - xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef[2]/stJob:name"), &tv); - tv.read("Best man"); - xmpData.add(Exiv2::XmpKey("Xmp.xmpBJ.JobRef[2]/stJob:role"), &tv); - - // ------------------------------------------------------------------------- - // Output XMP properties - for (Exiv2::XmpData::const_iterator md = xmpData.begin(); - md != xmpData.end(); ++md) { - std::cout << std::setfill(' ') << std::left - << std::setw(44) - << md->key() << " " - << std::setw(9) << std::setfill(' ') << std::left - << md->typeName() << " " - << std::dec << std::setw(3) - << std::setfill(' ') << std::right - << md->count() << " " - << std::dec << md->value() - << std::endl; - } - - // ------------------------------------------------------------------------- - // Serialize the XMP data and output the XMP packet - std::string xmpPacket; - if (0 != Exiv2::XmpParser::encode(xmpPacket, xmpData)) { - throw Exiv2::Error(1, "Failed to serialize XMP data"); - } - std::cout << xmpPacket << "\n"; - - // Cleanup - Exiv2::XmpParser::terminate(); - - return 0; -} -catch (Exiv2::AnyError& e) { - std::cout << "Caught Exiv2 exception '" << e << "'\n"; - return -1; -} -