Get interpreted value for a tag-value without saving it
Added by Norbert Wagner almost 3 years ago
I want to get the interpreted value of a tag after entering the "original" value, but without saving the image (as a preview for the user). E.g. after entering "53/10", writing the image and reading again, I get as interpreted value "F5.3".
This is my code:
Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::asciiString);
v->read("53/10");
Exiv2::ExifKey key("Exif.Photo.FNumber");
Exiv2::Exifdatum datum = Exiv2::Exifdatum(key, v.get());
std::cout << "key=" << datum.key().c_str() << " value=" << datum.toString().c_str() << " interpreted=" << datum.print().c_str() << "\n";
The result is:
key=Exif.Photo.FNumber value=53/10 interpreted=F53
When saving this value, F5.3 is returned.
When I try the value "800/10" with Exif.Photo.FocalLength, the returned interpreted value is "56.0 mm", really strange number.
Obviously the interpreted value in both cases is formated based on the tag (F for FNumber, mm for focal length), but the values do not fit.
Any idea how I can get the correct interpreted value?
Replies (4)
RE: Get interpreted value for a tag-value without saving it - Added by Robin Mills almost 3 years ago
Norbert
Seasons Greetings. Hope you're good. We released Exiv2 v0.27 today on http://exiv2.org
I think the "interpreted" value is returned by item.print()
and the ascii representation of the "raw" data by item.value().toString()
. I've modified my copy of sample/exifprint.cpp
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" */ std::cout << i->key() << "t,v = " << i->print() << "," << i->value().toString() << std::endl; }
Fnumbers is the mysterious "APEX" number. Phil explains this here: http://dev.exiv2.org/issues/1039#note-8
There are metadata items which are "protected". They are declared in src/tiffimage_int.cpp and considered part of the Image and can't be modified. Exif.Photo.FocalLength doesn't seem to one of them, although I can't change it in my favourite test image Stonehenge.jpg (which you can download).
552 rmills@rmillsmbp:~/gnu/github/exiv2/exiv2/build $ curl -O http://clanmills.com/Stonehenge.jpg % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 6599k 100 6599k 0 0 304k 0 0:00:21 0:00:21 --:--:-- 729k 553 rmills@rmillsmbp:~/gnu/github/exiv2/exiv2/build $ bin/exifprint Stonehenge.jpg | grep -i foc Exif.Photo.FocalLength t,v = 44.0 mm,440/10 Exif.Nikon3.Focus t,v = Automatic,AF-A Exif.NikonLd3.FocusPosition t,v = 148,148 Exif.NikonLd3.FocusDistance t,v = 31.62 m,140 Exif.NikonLd3.FocalLength t,v = 43.6 mm,75 Exif.NikonLd3.MinFocalLength t,v = 18.3 mm,45 Exif.NikonLd3.MaxFocalLength t,v = 254.0 mm,136 Exif.NikonLd3.MaxApertureAtMinFocal t,v = F3.6,44 Exif.NikonLd3.MaxApertureAtMaxFocal t,v = F6.3,64 Exif.NikonAf2.ContrastDetectAFInFocus t,v = 0,0 Exif.Photo.FocalLengthIn35mmFilm t,v = 66.0 mm,66 554 rmills@rmillsmbp:~/gnu/github/exiv2/exiv2/build $
There are "convertors" in Exiv2 which synchronise metadata between Exif, IPTC and XMP. I see Exif.NikonLd3.FocalLength is 43.6,75. I think the convertor is "forcing" the value of 44 into Exif.Photo.FocalLength.
I'm sure we'll be discussing this more in the next few days.
RE: Get interpreted value for a tag-value without saving it - Added by Norbert Wagner almost 3 years ago
Hi Robert,
Seasons Greetings and hoping you're good as well.
Thanks for your really fast response. As I noticed that my question seemed not to be clear enough, I wanted to enhance my example. And when I copied code from other places, I found the reason, why this was not working as I expected: using "Exiv2::asciiString" when initialising Exiv2::Value::AutoPtr was wrong. Here the code which gives the expected results:
Exiv2::ExifKey key("Exif.Photo.FNumber");
Exiv2::Value::AutoPtr v = Exiv2::Value::create(key.defaultTypeId());
v->read("53/10");
Exiv2::Exifdatum datum = Exiv2::Exifdatum(key, v.get());
std::cout << "key=" << datum.key().c_str() << " value=" << datum.toString().c_str() << " interpreted=" << datum.print().c_str() << "\"\n";
I downloaded your favourite test image (it's really nice) and was able to change Exif.Photo.FocalLength with my program.
Norbert
RE: Get interpreted value for a tag-value without saving it - Added by Robin Mills almost 3 years ago
Thanks for the update. It sounds as though this has a happy ending.
I've just pulled down a fresh copy of Stonehenge.jpg and I can edit FocalLength. I have no idea why it wouldn't cooperate yesterday.
$ curl -O http://clanmills.com/Stonehenge.jpg % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 6599k 100 6599k 0 0 1131k 0 0:00:05 0:00:05 --:--:-- 1484k $ exiv2 --version | grep 27 exiv2 0.27.0 $ exiv2 --key Exif.Photo.FocalLength Stonehenge.jpg Exif.Photo.FocalLength Rational 1 44.0 mm $ exiv2 -M'set Exif.Photo.FocalLength 100/1' Stonehenge.jpg $ exiv2 --key Exif.Photo.FocalLength Stonehenge.jpg Exif.Photo.FocalLength Rational 1 100.0 mm $
I live 90km from Stonehenge and there's nothing special/unusual about that photo. However, when I answer questions about Exiv2 on the forum, I like to use that image. Exiv2 can read (and write) images using http. Of course, you don't have write access to clanmills.com, so that's why I recommended to pull down the image with curl. However when only reading the image, exiv2's http I/O is fine:
$ exiv2 --key Exif.Photo.FocalLength http://clanmills.com/Stonehenge.jpg Exif.Photo.FocalLength Rational 1 44.0 mm $
I hope you've been able to build exiv2 v0.27 from the source 'bundle' with CMake. Happy to help if you're in difficulty.
Robin
RE: Get interpreted value for a tag-value without saving it - Added by Norbert Wagner almost 3 years ago
Today I made some more detailed tests with a set of images. In general the solution works fine, I found just one tag, where it is not giving the interpreted value: Exif.NikonSi02xx.Version. But I believe nobody has the intention to change it, and if he has to accept that the interpreted value is shown correct only after saving.
I did not yet start with CMake, need to get familiar with it first. Will contact you if I need help, thanks a lot for your offer.