예제 #1
0
 //for diagnostic
 void PrintTag(Exiv2::ExifData::iterator itr)
 {
     std::cout << itr->value() << " (" << itr->typeName() << ", size: " << itr->count() << ")" << std::endl;
     if(itr->count()>1)
     {
         std::cout << "[";
         for(long i=0; i<itr->count(); i++)
         {
             std::cout << itr->toFloat(i) << ",";
         }
         std::cout << "]" << std::endl;
     };
 };
예제 #2
0
QString Previewimage::getExifKey(QString key, Exiv2::ExifData *exifData){
    // returns string represented by exif key
    if(exifData == 0) return QString();
    QString ret;
    try {
        Exiv2::ExifData::iterator pos = exifData->findKey(
                    Exiv2::ExifKey(qPrintable(key)));
        if (pos == exifData->end()) return QString();
        else ret = QString().fromStdString(pos->value().toString());
    } catch (Exiv2::Error& e) {
        qCritical("[Rename] %s", e.what());
    }
    return ret;
}
예제 #3
0
// *****************************************************************************
// Main
int main()
try {
    // Container for all metadata
    Exiv2::ExifData exifData;

    // *************************************************************************
    // Add to the Exif data

    // Create a ASCII string value (note the use of create)
    Exiv2::Value* v = Exiv2::Value::create(Exiv2::asciiString);
    // Set the value to a string
    v->read("1999:12:31 23:59:59");
    // Add the value together with its key to the Exif data container
    Exiv2::ExifKey key("Exif.Photo.DateTimeOriginal");
    exifData.add(key, v);

    std::cout << "Added key \"" << key << "\", value \"" << *v << "\"\n";
    // Delete the memory allocated by Value::create
    delete v;

    // Now create a more interesting value (without using the create method)
    Exiv2::URationalValue* rv = new Exiv2::URationalValue;
    // Set two rational components from a string
    rv->read("1/2 1/3");
    // Add more elements through the extended interface of rational value 
    rv->value_.push_back(std::make_pair(2,3));
    rv->value_.push_back(std::make_pair(3,4));
    // Add the key and value pair to the Exif data
    key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
    exifData.add(key, rv);

    std::cout << "Added key \"" << key << "\", value \"" << *rv << "\"\n";
    // Delete memory allocated on the heap
    delete rv;

    // *************************************************************************
    // Modify Exif data

    // Find the timestamp metadatum by its key
    key = Exiv2::ExifKey("Exif.Photo.DateTimeOriginal");
    Exiv2::ExifData::iterator pos = exifData.findKey(key);
    if (pos == exifData.end()) throw Exiv2::Error("Key not found");
    // Modify the value
    std::string date = pos->toString();
    date.replace(0,4,"2000");
    pos->setValue(date); 
    std::cout << "Modified key \"" << key 
              << "\", new value \"" << pos->value() << "\"\n";

    // Find the other key
    key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
    pos = exifData.findKey(key);
    if (pos == exifData.end()) throw Exiv2::Error("Key not found");
    // Get a pointer to a copy of the value
    v = pos->getValue();
    // Downcast the Value pointer to its actual type
    rv = dynamic_cast<Exiv2::URationalValue*>(v);
    if (rv == 0) throw Exiv2::Error("Downcast failed");
    // Modify the value directly through the interface of URationalValue
    rv->value_[2] = std::make_pair(88,77);
    // Copy the modified value back to the metadatum
    pos->setValue(rv);
    // Delete the memory allocated by getValue
    delete v;
    std::cout << "Modified key \"" << key 
              << "\", new value \"" << pos->value() << "\"\n";

    // *************************************************************************
    // Delete metadata from the Exif data container

    // Delete the metadatum at iterator position pos
    key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
    pos = exifData.findKey(key);
    if (pos == exifData.end()) throw Exiv2::Error("Key not found");
    exifData.erase(pos);
    std::cout << "Deleted key \"" << key << "\"\n";

    // *************************************************************************
    // Finally, write the remaining Exif data to an image file
    int rc = exifData.write("img_2158.jpg");
    if (rc) {
        std::string error = Exiv2::ExifData::strError(rc, "img_2158.jpg");
        throw Exiv2::Error(error);
    }

    return 0;
}
catch (Exiv2::Error& e) {
    std::cout << "Caught Exiv2 exception '" << e << "'\n";
    return -1;
}
예제 #4
0
QgsPoint QgsExifTools::getGeoTag( const QString &imagePath, bool &ok )
{
  ok = false;
  if ( !QFileInfo::exists( imagePath ) )
    return QgsPoint();
  try
  {
    std::unique_ptr< Exiv2::Image > image( Exiv2::ImageFactory::open( imagePath.toStdString() ) );
    if ( !image )
      return QgsPoint();

    image->readMetadata();
    Exiv2::ExifData &exifData = image->exifData();

    if ( exifData.empty() )
      return QgsPoint();

    Exiv2::ExifData::iterator itLatRef = exifData.findKey( Exiv2::ExifKey( "Exif.GPSInfo.GPSLatitudeRef" ) );
    Exiv2::ExifData::iterator itLatVal = exifData.findKey( Exiv2::ExifKey( "Exif.GPSInfo.GPSLatitude" ) );
    Exiv2::ExifData::iterator itLonRef = exifData.findKey( Exiv2::ExifKey( "Exif.GPSInfo.GPSLongitudeRef" ) );
    Exiv2::ExifData::iterator itLonVal = exifData.findKey( Exiv2::ExifKey( "Exif.GPSInfo.GPSLongitude" ) );

    if ( itLatRef == exifData.end() || itLatVal == exifData.end() ||
         itLonRef == exifData.end() || itLonVal == exifData.end() )
      return QgsPoint();

    auto readCoord = []( const QString & coord )->double
    {
      double res = 0;
      double div = 1;
      const QStringList parts = coord.split( QRegularExpression( QStringLiteral( "\\s+" ) ) );
      for ( const QString &rational : parts )
      {
        const QStringList pair = rational.split( '/' );
        if ( pair.size() != 2 )
          break;
        res += ( pair[0].toDouble() / pair[1].toDouble() ) / div;
        div *= 60;
      }
      return res;
    };

    auto readRationale = []( const QString & rational )->double
    {
      const QStringList pair = rational.split( '/' );
      if ( pair.size() != 2 )
        return std::numeric_limits< double >::quiet_NaN();
      return pair[0].toDouble() / pair[1].toDouble();
    };

    double lat = readCoord( QString::fromStdString( itLatVal->value().toString() ) );
    double lon = readCoord( QString::fromStdString( itLonVal->value().toString() ) );

    const QString latRef = QString::fromStdString( itLatRef->value().toString() );
    const QString lonRef = QString::fromStdString( itLonRef->value().toString() );
    if ( latRef.compare( QLatin1String( "S" ), Qt::CaseInsensitive ) == 0 )
    {
      lat *= -1;
    }
    if ( lonRef.compare( QLatin1String( "W" ), Qt::CaseInsensitive ) == 0 )
    {
      lon *= -1;
    }

    ok = true;

    Exiv2::ExifData::iterator itElevVal = exifData.findKey( Exiv2::ExifKey( "Exif.GPSInfo.GPSAltitude" ) );
    Exiv2::ExifData::iterator itElevRefVal = exifData.findKey( Exiv2::ExifKey( "Exif.GPSInfo.GPSAltitudeRef" ) );
    if ( itElevVal != exifData.end() )
    {
      double elev = readRationale( QString::fromStdString( itElevVal->value().toString() ) );
      if ( itElevRefVal != exifData.end() )
      {
        const QString elevRef = QString::fromStdString( itElevRefVal->value().toString() );
        if ( elevRef.compare( QLatin1String( "1" ), Qt::CaseInsensitive ) == 0 )
        {
          elev *= -1;
        }
      }
      return QgsPoint( lon, lat, elev );
    }
    else
    {
      return QgsPoint( lon, lat );
    }
  }
  catch ( ... )
  {
    return QgsPoint();
  }
}