Project

General

Profile

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.

    (1-4/4)