00001 // ***************************************************************** -*- C++ -*- 00002 // addmoddel.cpp, $Rev: 631 $ 00003 // Sample program showing how to add, modify and delete Exif metadata. 00004 00005 #include "image.hpp" 00006 #include "exif.hpp" 00007 #include <iostream> 00008 #include <iomanip> 00009 #include <cassert> 00010 00011 int main(int argc, char* const argv[]) 00012 try { 00013 if (argc != 2) { 00014 std::cout << "Usage: " << argv[0] << " file\n"; 00015 return 1; 00016 } 00017 std::string file(argv[1]); 00018 00019 // Container for exif metadata. This is an example of creating 00020 // exif metadata from scratch. If you want to add, modify, delete 00021 // metadata that exists in an image, start with ImageFactory::open 00022 Exiv2::ExifData exifData; 00023 00024 // ************************************************************************* 00025 // Add to the Exif data 00026 00027 // This is the quickest way to add (simple) Exif data. If a metadatum for 00028 // a given key already exists, its value is overwritten. Otherwise a new 00029 // tag is added. 00030 exifData["Exif.Image.Model"] = "Test 1"; // AsciiValue 00031 exifData["Exif.Image.SamplesPerPixel"] = uint16_t(162); // UShortValue 00032 exifData["Exif.Image.XResolution"] = int32_t(-2); // LongValue 00033 exifData["Exif.Image.YResolution"] = Exiv2::Rational(-2, 3); // RationalValue 00034 std::cout << "Added a few tags the quick way.\n"; 00035 00036 // Create a ASCII string value (note the use of create) 00037 Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::asciiString); 00038 // Set the value to a string 00039 v->read("1999:12:31 23:59:59"); 00040 // Add the value together with its key to the Exif data container 00041 Exiv2::ExifKey key("Exif.Photo.DateTimeOriginal"); 00042 exifData.add(key, v.get()); 00043 std::cout << "Added key \"" << key << "\", value \"" << *v << "\"\n"; 00044 00045 // Now create a more interesting value (without using the create method) 00046 Exiv2::URationalValue::AutoPtr rv(new Exiv2::URationalValue); 00047 // Set two rational components from a string 00048 rv->read("1/2 1/3"); 00049 // Add more elements through the extended interface of rational value 00050 rv->value_.push_back(std::make_pair(2,3)); 00051 rv->value_.push_back(std::make_pair(3,4)); 00052 // Add the key and value pair to the Exif data 00053 key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities"); 00054 exifData.add(key, rv.get()); 00055 std::cout << "Added key \"" << key << "\", value \"" << *rv << "\"\n"; 00056 00057 // ************************************************************************* 00058 // Modify Exif data 00059 00060 // Since we know that the metadatum exists (or we don't mind creating a new 00061 // tag if it doesn't), we can simply do this: 00062 Exiv2::Exifdatum& tag = exifData["Exif.Photo.DateTimeOriginal"]; 00063 std::string date = tag.toString(); 00064 date.replace(0, 4, "2000"); 00065 tag.setValue(date); 00066 std::cout << "Modified key \"" << key 00067 << "\", new value \"" << tag.value() << "\"\n"; 00068 00069 // Alternatively, we can use findKey() 00070 key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities"); 00071 Exiv2::ExifData::iterator pos = exifData.findKey(key); 00072 if (pos == exifData.end()) throw Exiv2::Error(1, "Key not found"); 00073 // Get a pointer to a copy of the value 00074 v = pos->getValue(); 00075 // Downcast the Value pointer to its actual type 00076 Exiv2::URationalValue* prv = dynamic_cast<Exiv2::URationalValue*>(v.release()); 00077 if (prv == 0) throw Exiv2::Error(1, "Downcast failed"); 00078 rv = Exiv2::URationalValue::AutoPtr(prv); 00079 // Modify the value directly through the interface of URationalValue 00080 rv->value_[2] = std::make_pair(88,77); 00081 // Copy the modified value back to the metadatum 00082 pos->setValue(rv.get()); 00083 std::cout << "Modified key \"" << key 00084 << "\", new value \"" << pos->value() << "\"\n"; 00085 00086 // ************************************************************************* 00087 // Delete metadata from the Exif data container 00088 00089 // Delete the metadatum at iterator position pos 00090 key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities"); 00091 pos = exifData.findKey(key); 00092 if (pos == exifData.end()) throw Exiv2::Error(1, "Key not found"); 00093 exifData.erase(pos); 00094 std::cout << "Deleted key \"" << key << "\"\n"; 00095 00096 // ************************************************************************* 00097 // Finally, write the remaining Exif data to the image file 00098 Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(file); 00099 assert(image.get() != 0); 00100 00101 image->setExifData(exifData); 00102 image->writeMetadata(); 00103 00104 return 0; 00105 } 00106 catch (Exiv2::AnyError& e) { 00107 std::cout << "Caught Exiv2 exception '" << e << "'\n"; 00108 return -1; 00109 }