Pong

October 30th 2014, Geo-tagging with libexiv2

October 29th 2014 Exiv2 Revisited | | October 31th 2014 Evaluation of libexiv2

With libexiv2 geo-tagging a JPEG file is easily accomplished.

First, we assume that the actual location is provided by a GPS device as lat, lon and alt. Then we add the respective geo-tags to a JPEG file with a specific path as follows:

#include <exiv2/exif.hpp>
#include <exiv2/image.hpp>

// convert double to rational
Exiv2::Rational double2rational(double value, int denom)
{
   return(Exiv2::Rational((int)(value*denom+0.5), denom));
}

// geo-tag image file
bool geotag(std::string path, double lat, double lon, double alt)
{
   Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path);
   if (image.get())
   {
      // load EXIF data from file
      image->readMetadata();
      Exiv2::ExifData exifData = image->exifData();

      // create EXIF GPSAltitude entry
      exifData["Exif.GPSInfo.GPSAltitude"] = double2rational(alt, 1000); // mm
      exifData["Exif.GPSInfo.GPSAltitudeRef"] = uint8_t(0); // m.a.s.l.

      // create EXIF GPSLatitude entry
      Exiv2::RationalValue::AutoPtr rvlat(new Exiv2::RationalValue);
      rvlat->value_.push_back(double2rational(trunc(lat), 1)); // arcdeg
      rvlat->value_.push_back(double2rational((lat-trunc(lat))*60, 10000)); // arcmin
      rvlat->value_.push_back(std::make_pair(0, 1)); // arcsec
      exifData.add(Exiv2::ExifKey("Exif.GPSInfo.GPSLatitude"), rvlat.get());
      exifData["Exif.GPSInfo.GPSLatitudeRef"] = "N"; // northing

      // create EXIF GPSLongitude entry
      Exiv2::RationalValue::AutoPtr rvlon(new Exiv2::RationalValue);
      rvlon->value_.push_back(double2rational(trunc(lon), 1)); // arcdeg
      rvlon->value_.push_back(double2rational((lon-trunc(lon))*60, 10000)); // arcmin
      rvlon->value_.push_back(std::make_pair(0, 1)); // arcsec
      exifData.add(Exiv2::ExifKey("Exif.GPSInfo.GPSLongitude"), rvlon.get());
      exifData["Exif.GPSInfo.GPSLongitudeRef"] = "E"; // easting

      // save EXIF data to file
      image->setExifData(exifData);
      image->writeMetadata();

      return(true);
   }

   return(false);
}

Besides adding the GPS EXIF tags GPSAltitude, GPSAltitudeRef, GPSLatitude, GPSLatitudeRef, GPSLongitude and GPSLongitudeRef, as demonstrated above, the optional GPS tags GPSTimeStamp, GPSDateStamp and GPSDOP can be set with libexiv2 in a similar fashion.

Here is the first image geo-tagged with the above code, literally:

GeoTagged


October 29th 2014 Exiv2 Revisited | | October 31th 2014 Evaluation of libexiv2

Options: