Project

General

Profile

Magick++ and Exiv2

Added by gary cohen about 12 years ago

Hi,

I'm using ImageMagick (Magick++ to be more specific) and I need to write out some updated EXIF metadata to an already loaded image. To get the existing EXIF metadata I make this call in IM:

Magick::Blob exifProfile = image.profile("exif");

Once loaded I try this:

Exiv2::ExifData exifData;
Exiv2::ByteOrder order = Exiv2::ExifParser::decode( exifData, (Exiv2::byte *)exifProfile.data(), (uint32_t)exifProfile.length() );

But when I do this I get an exception saying it's not a valid TIFF file. I stepped through your code and see that the ExifParser just runs into the TIFF code, and since this is just the metadata itself, I see why the error is happening.

So, I changed the part part to this:

Magick::Blob exifProfile;
image.write( & exifProfile, "TIFF" );

And now when I decode, it works. I'm not sure if this is the best way to do things (I'd like not to have to create a new image just to edit the metadata). When I try to export the metadata back into just pure metadata I'm running into trouble:

Exiv2::Blob exivBlob;
Exiv2::ExifParser::encode( exivBlob, order, exifData );
Magick::Blob magickBlob( (const void *)&exivBlob[0], exivBlob.size() );
image.exifProfile( magickBlob );

It just blows away the entire metadata for my original image. Can I use Exiv2 to do what I'm trying to do? Where am I going wrong?

Thanks in advance,
-gary


Replies (2)

RE: Magick++ and Exiv2 - Added by Andreas Huggel about 12 years ago

Hi Gary,

The most straighforward way is to let Exiv2 operate on the complete image for both reading the metadata and writing it back. The image can be on the filesystem or in memory for that (see ImageFactory::open()).

For anything else, it is crucial to understand exactly what data is passed from one library to the other and image formats to some extent. Then it may be possible to use IM to extract the binary Exif data from an image, pass it to Exiv2 to decode, modify and re-encode it and use IM again to insert it back into the image. Using an Exiv2::*Parser class is the correct approach for that, which parser depends on the image format and the data must start with a TIFF header (Exif binary data is stored like that even in a JPEG image - there should definitely not be a need to save it as a TIFF image first. What exactly does image.profile("exif") return?). This method is more likely to work for a JPEG or PNG image and rather unlikely to work for any TIFF-like image. I recommend not to bother with all of this and use the straightforward way.

Andreas

RE: Magick++ and Exiv2 - Added by gary cohen about 12 years ago

Thanks. I ended up using your first recommendation, but since my image is in memory, this workflow requires me to essentially double the amount of memory I'm using. In any event, this is done on thumbnails, so it's not that big of a deal.

    (1-2/2)