You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
exiv2/src/exifcomment.cpp

91 lines
3.2 KiB
C++

// ***************************************************************** -*- C++ -*-
/*
Abstract : Sample program showing how to set the Exif comment of an image
File: exifcomment.cpp
Version : $Name: $ $Revision: 1.4 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History : 10-May-04, ahu: created
*/
// *****************************************************************************
// included header files
#include "exif.hpp"
#include <iostream>
#include <iomanip>
#include <cstring>
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
try {
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " file\n";
return 1;
}
Exiv2::ExifData exifData;
int rc = exifData.read(argv[1]);
if (rc) {
std::string error = Exiv2::ExifData::strError(rc, argv[1]);
throw Exiv2::Error(error);
}
/*
There are two pitfalls that we need to consider when setting the Exif user
comment (Exif.Photo.UserComment) of an image:
First, the type of the Exif user comment tag is "undefined" (and not
ASCII) according to the Exif standard. This means that in Exiv2, we have
to deal with a DataValue (and not an AsciiValue). DataValue has the usual
two read methods, however, the one taking a const std::string& buf expects
the string to contain a series of integers (e.g., "0 1 2") and not a text
string. Thus, we need to use the read function that reads the value from a
character buffer of a given length.
Second, the Exif comment field starts with an eight character area that
identifies the used character set. For ASCII, these eight characters are
"ASCII\0\0\0". The actual comment follows after this code.
Note: There is a more simple Exif tag for the title of an image. It is a
20 byte string (type ASCII) and does not store two-byte characters.
(Image.OtherTags.ImageDescription)
*/
// Initialise a data value with the character set and comment
std::string charset("ASCII\0\0\0", 8);
std::string comment("A comment added to the Exif metadata through Exiv2");
Exiv2::DataValue value;
value.read(reinterpret_cast<const Exiv2::byte*>((charset + comment).data()),
8 + static_cast<long>(comment.size()));
// Set the Exif comment
Exiv2::ExifKey key("Exif.Photo.UserComment");
Exiv2::ExifData::iterator pos = exifData.findKey(key);
if (pos != exifData.end()) {
// Use the existing Exif UserComment metadatum if there is one
pos->setValue(&value);
}
else {
// Otherwise add a new UserComment metadatum
exifData.add(key, &value);
pos = exifData.findKey(key);
}
// Now we should have a valid iterator in any case. We use the metadatum
// output operator to print the formatted value
std::cout << "Writing user comment '" << *pos << "' back to the image\n";
rc = exifData.write(argv[1]);
if (rc) {
std::string error = Exiv2::ExifData::strError(rc, argv[1]);
throw Exiv2::Error(error);
}
return rc;
}
catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}