QString exifDataToString(Exiv2::ExifData exifData) {
    if (exifData.empty()) {
        return QString(QObject::tr("No EXIF found"));
    }
    try {
        Exiv2::ExifData::const_iterator end = exifData.end();
        QString tmpExif, final;
        for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
            const char* tn = i->typeName();
            /*std::string str = 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";*/
            tmpExif = "<span style='color:#1cb495;'>" + QString::fromStdString(i->key()).split(".").at(2) + "</span>&emsp;" +
                      //QString::number(i->tag()) + "\t" +
                      //(tn ? tn : "Unknown") + "\t" +
                      //QString::number(i->count()) + "\t" +
                      QString::fromStdString(i->value().toString()) + "<br />";
            final.append(tmpExif);
        }
        return final;
    } catch(Exiv2::Error& e) {
Beispiel #2
0
void print(const std::string& file)
{
    Exiv2::ExifData ed;
    int rc = ed.read(file);
    if (rc) {
        std::string error = Exiv2::ExifData::strError(rc, file);
        throw Exiv2::Error(error);
    }

    Exiv2::ExifData::const_iterator end = ed.end();
    for (Exiv2::ExifData::const_iterator i = ed.begin(); i != end; ++i) {
        std::cout << std::setw(45) << std::setfill(' ') << std::left
                  << i->key() << " "
                  << "0x" << std::setw(4) << std::setfill('0') << std::right
                  << std::hex << i->tag() << " " 
                  << std::setw(12) << std::setfill(' ') << std::left
                  << i->ifdName() << " "
                  << std::setw(9) << std::setfill(' ') << std::left
                  << i->typeName() << " "
                  << std::dec << std::setw(3) 
                  << std::setfill(' ') << std::right
                  << i->count() << " "
                  << std::dec << i->value() 
                  << "\n";

    }
}
Beispiel #3
0
static void EraseGpsTags(Exiv2::ExifData &ExifInfo)
{
	// Search through, find the keys that we want, and wipe them
	// Code below submitted by Marc Horowitz
	Exiv2::ExifData::iterator Iter;
	for (Exiv2::ExifData::iterator Iter = ExifInfo.begin();
		Iter != ExifInfo.end(); )
	{
		if (Iter->key().find("Exif.GPSInfo") == 0)
			Iter = ExifInfo.erase(Iter);
		else
			Iter++;
	}
}
// uses the exiv2 class to readout the exifdata from images
int ExifScout::showExifData(std::string a){
    try {
        Ui_MainWindow::textEdit->clear();
        std::cerr << "ImageFactory::open ";
        Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(a);
        std::cerr << "DONE\n";
        assert(image.get() != 0);

        std::cerr << "image->readMetadata() ";
        image->readMetadata();
        std::cerr << "DONE\n";

        std::cerr << "Exiv2::ExifData& exifData = image->exifData() ";
        Exiv2::ExifData exifData = image->exifData();
        std::cerr << "DONE\n";

	cout << "Number of found exiv2 data: " << exifData.count() << endl;
        if (exifData.empty()) {
            Ui_MainWindow::textEdit->setPlainText("No Exif data found in file");
            return 1;
        }

        Exiv2::ExifData::const_iterator end = exifData.end();
        std::cerr << "Generate the exif-output ";
        QString output;
        for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
            std::string tagname = i->tagName();

            if(tagname != std::string("MakerNote") and
               tagname.substr(0,2) != "0x"){
                // Print out the exif-data in the QtextEdit Field
                std::ostringstream oss;
                oss << i->tagName() << ":\n    " << i->value() << "\n";
                output = output+(QString)oss.str().c_str();
            }
        }
        std::cerr << "Done\n";
        Ui_MainWindow::textEdit->setPlainText(output);

        return 0;
    }
    //catch (std::exception& e) {
    //catch (Exiv2::AnyError& e) {
    catch (Exiv2::Error& e) {
        std::cout << "Caught Exiv2 exception '" << e.what() << "'\n";
        return -1;
    }
}
// tries to find a specified exif tag in a specified file
QString ExifScout::getExifData(QString fname, QString etag){
    std::string filename = fname.toAscii().data();
    std::string exiftag = etag.toAscii().data();

    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(filename);
    assert(image.get() != 0);
    image->readMetadata();
    Exiv2::ExifData exifData = image->exifData();
    if (!exifData.empty()) {
        Exiv2::ExifData::const_iterator end = exifData.end();
        QString output;
        for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
            if(i->tagName()==exiftag){
                std::ostringstream oss;
                oss << i->value();
                return (QString)oss.str().c_str();
            }
        }
    }
    return NULL;
}
Beispiel #6
0
bool KExiv2::Private::saveOperations(const QFileInfo& finfo, Exiv2::Image::AutoPtr image) const
{
    try
    {
        Exiv2::AccessMode mode;
        bool wroteComment = false, wroteEXIF = false, wroteIPTC = false, wroteXMP = false;

        // We need to load target file metadata to merge with new one. It's mandatory with TIFF format:
        // like all tiff file structure is based on Exif.
        image->readMetadata();

        // Image Comments ---------------------------------

        mode = image->checkMode(Exiv2::mdComment);

        if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite))
        {
            image->setComment(imageComments());
            wroteComment = true;
        }

        // Exif metadata ----------------------------------

        mode = image->checkMode(Exiv2::mdExif);

        if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite))
        {
            if (image->mimeType() == "image/tiff")
            {
                Exiv2::ExifData orgExif = image->exifData();
                Exiv2::ExifData newExif;
                QStringList     untouchedTags;

                // With tiff image we cannot overwrite whole Exif data as well, because
                // image data are stored in Exif container. We need to take a care about
                // to not lost image data.
                untouchedTags << "Exif.Image.ImageWidth";
                untouchedTags << "Exif.Image.ImageLength";
                untouchedTags << "Exif.Image.BitsPerSample";
                untouchedTags << "Exif.Image.Compression";
                untouchedTags << "Exif.Image.PhotometricInterpretation";
                untouchedTags << "Exif.Image.FillOrder";
                untouchedTags << "Exif.Image.SamplesPerPixel";
                untouchedTags << "Exif.Image.StripOffsets";
                untouchedTags << "Exif.Image.RowsPerStrip";
                untouchedTags << "Exif.Image.StripByteCounts";
                untouchedTags << "Exif.Image.XResolution";
                untouchedTags << "Exif.Image.YResolution";
                untouchedTags << "Exif.Image.PlanarConfiguration";
                untouchedTags << "Exif.Image.ResolutionUnit";

                for (Exiv2::ExifData::iterator it = orgExif.begin(); it != orgExif.end(); ++it)
                {
                    if (untouchedTags.contains(it->key().c_str()))
                    {
                        newExif[it->key().c_str()] = orgExif[it->key().c_str()];
                    }
                }

                Exiv2::ExifData readedExif = exifMetadata();

                for (Exiv2::ExifData::iterator it = readedExif.begin(); it != readedExif.end(); ++it)
                {
                    if (!untouchedTags.contains(it->key().c_str()))
                    {
                        newExif[it->key().c_str()] = readedExif[it->key().c_str()];
                    }
                }

                image->setExifData(newExif);
            }
            else
            {
                image->setExifData(exifMetadata());
            }

            wroteEXIF = true;
        }

        // Iptc metadata ----------------------------------

        mode = image->checkMode(Exiv2::mdIptc);

        if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite))
        {
            image->setIptcData(iptcMetadata());
            wroteIPTC = true;
        }

        // Xmp metadata -----------------------------------

        mode = image->checkMode(Exiv2::mdXmp);

        if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite))
        {
#ifdef _XMP_SUPPORT_
            image->setXmpData(xmpMetadata());
            wroteXMP = true;
#endif
        }

        if (!wroteComment && !wroteEXIF && !wroteIPTC && !wroteXMP)
        {
            kDebug() << "Writing metadata is not supported for file" << finfo.fileName();
            return false;
        }
        else if (!wroteEXIF || !wroteIPTC || !wroteXMP)
        {
            kDebug() << "Support for writing metadata is limited for file" << finfo.fileName()
                     << "EXIF" << wroteEXIF << "IPTC" << wroteIPTC << "XMP" << wroteXMP;
        }

        if (!updateFileTimeStamp)
        {
            // Don't touch access and modification timestamp of file.
            struct stat st;
            ::stat(QFile::encodeName(filePath), &st);

            struct utimbuf ut;
            ut.modtime = st.st_mtime;
            ut.actime  = st.st_atime;

            image->writeMetadata();

            ::utime(QFile::encodeName(filePath), &ut);
        }
        else
        {
            image->writeMetadata();
        }

        return true;
    }
    catch( Exiv2::Error& e )
    {
        printExiv2ExceptionError("Cannot save metadata using Exiv2 ", e);
    }

    return false;
}
Beispiel #7
0
bool ptImageHelper::WriteExif(const QString              &AFileName,
                              const std::vector<uint8_t> &AExifBuffer,
                              Exiv2::IptcData            &AIptcData,
                              Exiv2::XmpData             &AXmpData) {
  try {
#if EXIV2_TEST_VERSION(0,17,91)   /* Exiv2 0.18-pre1 */

    Exiv2::ExifData hInExifData;

    Exiv2::ExifParser::decode(hInExifData,
                              AExifBuffer.data() + CExifHeader.size(),
                              AExifBuffer.size() - CExifHeader.size());

    // Reset orientation
    Exiv2::ExifData::iterator pos = hInExifData.begin();
    if ((pos = hInExifData.findKey(Exiv2::ExifKey("Exif.Image.Orientation"))) != hInExifData.end()) {
      pos->setValue("1"); // Normal orientation
    }

    // Adapted from UFRaw, necessary for Tiff files
    QStringList ExifKeys;
    ExifKeys  << "Exif.Image.ImageWidth"
              << "Exif.Image.ImageLength"
              << "Exif.Image.BitsPerSample"
              << "Exif.Image.Compression"
              << "Exif.Image.PhotometricInterpretation"
              << "Exif.Image.FillOrder"
              << "Exif.Image.SamplesPerPixel"
              << "Exif.Image.StripOffsets"
              << "Exif.Image.RowsPerStrip"
              << "Exif.Image.StripByteCounts"
              << "Exif.Image.XResolution"
              << "Exif.Image.YResolution"
              << "Exif.Image.PlanarConfiguration"
              << "Exif.Image.ResolutionUnit";

    for (short i = 0; i < ExifKeys.count(); i++) {
      if ((pos = hInExifData.findKey(Exiv2::ExifKey(ExifKeys.at(i).toLocal8Bit().data()))) != hInExifData.end())
        hInExifData.erase(pos);
    }

    if (Settings->GetInt("EraseExifThumbnail")) {
      Exiv2::ExifThumb Thumb(hInExifData);
      Thumb.erase();
    }

    QStringList JpegExtensions;
    JpegExtensions << "jpg" << "JPG" << "Jpg" << "jpeg" << "Jpeg" << "JPEG";
    bool deleteDNGdata = false;
    for (short i = 0; i < JpegExtensions.count(); i++) {
      if (!AFileName.endsWith(JpegExtensions.at(i))) deleteDNGdata = true;
    }

    Exiv2::Image::AutoPtr Exiv2Image = Exiv2::ImageFactory::open(AFileName.toLocal8Bit().data());

    Exiv2Image->readMetadata();
    Exiv2::ExifData outExifData = Exiv2Image->exifData();

    for (auto hPos = hInExifData.begin(); hPos != hInExifData.end(); hPos++) {
      if (!deleteDNGdata || (*hPos).key() != "Exif.Image.DNGPrivateData") {
        outExifData.add(*hPos);
      }
    }

    // IPTC data

    QStringList Tags        = Settings->GetStringList("TagsList");
    QStringList DigikamTags = Settings->GetStringList("DigikamTagsList");

    Exiv2::StringValue StringValue;
    for (int i = 0; i < Tags.size(); i++) {
      StringValue.read(Tags.at(i).toStdString());
      AIptcData.add(Exiv2::IptcKey("Iptc.Application2.Keywords"), &StringValue);
    }


    // XMP data

    for (int i = 0; i < Tags.size(); i++) {
      AXmpData["Xmp.dc.subject"] = Tags.at(i).toStdString();
    }
    for (int i = 0; i < DigikamTags.size(); i++) {
      AXmpData["Xmp.digiKam.TagsList"] = DigikamTags.at(i).toStdString();
    }

    // Image rating
    outExifData["Exif.Image.Rating"] = Settings->GetInt("ImageRating");
    AXmpData["Xmp.xmp.Rating"]       = Settings->GetInt("ImageRating");

    // Program name
    outExifData["Exif.Image.ProcessingSoftware"]  = ProgramName;
    outExifData["Exif.Image.Software"]            = ProgramName;
    AIptcData["Iptc.Application2.Program"]        = ProgramName;
    AIptcData["Iptc.Application2.ProgramVersion"] = "idle";
    AXmpData["Xmp.xmp.CreatorTool"]               = ProgramName;
    AXmpData["Xmp.tiff.Software"]                 = ProgramName;

    // Title
    QString TitleWorking = Settings->GetString("ImageTitle");
    StringClean(TitleWorking);
    if (TitleWorking != "") {
      outExifData["Exif.Photo.UserComment"]  = TitleWorking.toStdString();
      AIptcData["Iptc.Application2.Caption"] = TitleWorking.toStdString();
      AXmpData["Xmp.dc.description"]         = TitleWorking.toStdString();
      AXmpData["Xmp.exif.UserComment"]       = TitleWorking.toStdString();
      AXmpData["Xmp.tiff.ImageDescription"]  = TitleWorking.toStdString();
    }

    // Copyright
    QString CopyrightWorking = Settings->GetString("Copyright");
    StringClean(CopyrightWorking);
    if (CopyrightWorking != "") {
      outExifData["Exif.Image.Copyright"]      = CopyrightWorking.toStdString();
      AIptcData["Iptc.Application2.Copyright"] = CopyrightWorking.toStdString();
      AXmpData["Xmp.tiff.Copyright"]           = CopyrightWorking.toStdString();
    }

    Exiv2Image->setExifData(outExifData);
    Exiv2Image->setIptcData(AIptcData);
    Exiv2Image->setXmpData(AXmpData);
    Exiv2Image->writeMetadata();
    return true;
#endif
  } catch (Exiv2::AnyError& Error) {
    if (Settings->GetInt("JobMode") == 0) {
      ptMessageBox::warning(0 ,"Exiv2 Error","No exif data written!\nCaught Exiv2 exception '" + QString(Error.what()) + "'\n");
    } else {
      std::cout << "Caught Exiv2 exception '" << Error << "'\n";
    }
  }
  return false;
}
Beispiel #8
0
bool KisExifIO::loadFrom(KisMetaData::Store* store, QIODevice* ioDevice) const
{
    ioDevice->open(QIODevice::ReadOnly);
    if (!ioDevice->isOpen()) {
        return false;
    }
    QByteArray arr = ioDevice->readAll();
    Exiv2::ExifData exifData;
    Exiv2::ByteOrder byteOrder;
#if EXIV2_MAJOR_VERSION == 0 && EXIV2_MINOR_VERSION <= 17
    exifData.load((const Exiv2::byte*)arr.data(), arr.size());
    byteOrder = exifData.byteOrder();
#else
    try {
        byteOrder = Exiv2::ExifParser::decode(exifData, (const Exiv2::byte*)arr.data(), arr.size());
    }
    catch (const std::exception& ex) {
        warnKrita << "Received exception trying to parse exiv data" << ex.what();
        return false;
    }
    catch (...) {
        dbgKrita << "Received unknown exception trying to parse exiv data";
        return false;
    }

#endif
    dbgFile << "Byte order = " << byteOrder << ppVar(Exiv2::bigEndian) << ppVar(Exiv2::littleEndian);
    dbgFile << "There are" << exifData.count() << " entries in the exif section";
    const KisMetaData::Schema* tiffSchema = KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::TIFFSchemaUri);
    Q_ASSERT(tiffSchema);
    const KisMetaData::Schema* exifSchema = KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::EXIFSchemaUri);
    Q_ASSERT(exifSchema);
    const KisMetaData::Schema* dcSchema = KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::DublinCoreSchemaUri);
    Q_ASSERT(dcSchema);
    const KisMetaData::Schema* xmpSchema = KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::XMPSchemaUri);
    Q_ASSERT(xmpSchema);
    for (Exiv2::ExifMetadata::const_iterator it = exifData.begin();
            it != exifData.end(); ++it) {
        if (it->key() == "Exif.Photo.StripOffsets"
                || it->key() == "RowsPerStrip"
                || it->key() == "StripByteCounts"
                || it->key() == "JPEGInterchangeFormat"
                || it->key() == "JPEGInterchangeFormatLength"
                || it->tagName() == "0x0000" ) {
            dbgFile << it->key().c_str() << " is ignored";
        } else if (it->key() == "Exif.Photo.MakerNote") {
            const KisMetaData::Schema* makerNoteSchema = KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::MakerNoteSchemaUri);
            store->addEntry(KisMetaData::Entry(makerNoteSchema, "RawData", exivValueToKMDValue(it->getValue(), false)));
        } else if (it->key() == "Exif.Image.DateTime") { // load as xmp:ModifyDate
            store->addEntry(KisMetaData::Entry(xmpSchema, "ModifyDate", KisMetaData::Value(exivValueToDateTime(it->getValue()))));
        } else if (it->key() == "Exif.Image.ImageDescription") { // load as "dc:description"
            store->addEntry(KisMetaData::Entry(dcSchema, "description", exivValueToKMDValue(it->getValue(), false)));
        } else if (it->key() == "Exif.Image.Software") { // load as "xmp:CreatorTool"
            store->addEntry(KisMetaData::Entry(xmpSchema, "CreatorTool", exivValueToKMDValue(it->getValue(), false)));
        } else if (it->key() == "Exif.Image.Artist") { // load as dc:creator
            QList<KisMetaData::Value> creators;
            creators.push_back(exivValueToKMDValue(it->getValue(), false));
            store->addEntry(KisMetaData::Entry(dcSchema, "creator", KisMetaData::Value(creators, KisMetaData::Value::OrderedArray)));
        } else if (it->key() == "Exif.Image.Copyright") { // load as dc:rights
            store->addEntry(KisMetaData::Entry(dcSchema, "rights", exivValueToKMDValue(it->getValue(), false)));
        } else if (it->groupName() == "Image") {
            // Tiff tags
            QString fixedTN = it->tagName().c_str();
            if (it->key() == "Exif.Image.ExifTag") {
                dbgFile << "Ignoring " << it->key().c_str();
            } else if (KisMetaData::Entry::isValidName(fixedTN)) {
                store->addEntry(KisMetaData::Entry(tiffSchema, fixedTN, exivValueToKMDValue(it->getValue(), false))) ;
            } else {
                dbgFile << "Invalid tag name: " << fixedTN;
            }
        } else if (it->groupName() == "Photo" || (it->groupName() == "GPS")) {
            // Exif tags (and GPS tags)
            KisMetaData::Value v;
            if (it->key() == "Exif.Photo.ExifVersion" || it->key() == "Exif.Photo.FlashpixVersion") {
                v = exifVersionToKMDValue(it->getValue());
            } else if (it->key() == "Exif.Photo.FileSource") {
                v = KisMetaData::Value(3);
            } else if (it->key() == "Exif.Photo.SceneType") {
                v = KisMetaData::Value(1);
            } else if (it->key() == "Exif.Photo.ComponentsConfiguration") {
                v = exifArrayToKMDIntOrderedArray(it->getValue());
            } else if (it->key() == "Exif.Photo.OECF") {
                v = exifOECFToKMDOECFStructure(it->getValue(), byteOrder);
            } else if (it->key() == "Exif.Photo.DateTimeDigitized" || it->key() == "Exif.Photo.DateTimeOriginal") {
                v = KisMetaData::Value(exivValueToDateTime(it->getValue()));
            } else if (it->key() == "Exif.Photo.DeviceSettingDescription") {
                v = deviceSettingDescriptionExifToKMD(it->getValue());
            } else if (it->key() == "Exif.Photo.CFAPattern") {
                v = cfaPatternExifToKMD(it->getValue(), byteOrder);
            } else if (it->key() == "Exif.Photo.Flash") {
                v = flashExifToKMD(it->getValue());
            } else if (it->key() == "Exif.Photo.UserComment") {
                KisMetaData::Value vUC = exivValueToKMDValue(it->getValue(), false);
                Q_ASSERT(vUC.type() == KisMetaData::Value::Variant);
                QVariant commentVar = vUC.asVariant();
                QString comment;
                if (commentVar.type() == QVariant::String) {
                    comment = commentVar.toString();
                } else if (commentVar.type() == QVariant::ByteArray) {
                    const QByteArray commentString = commentVar.toByteArray();
                    comment = QString::fromLatin1(commentString.constData(), commentString.size());
                } else {
                    warnKrita << "KisExifIO: Unhandled UserComment value type.";
                }
                KisMetaData::Value vcomment(comment);
                vcomment.addPropertyQualifier("xml:lang", KisMetaData::Value("x-default"));
                QList<KisMetaData::Value> alt;
                alt.append(vcomment);
                v = KisMetaData::Value(alt, KisMetaData::Value::LangArray);
            } else {
                bool forceSeq = false;
                KisMetaData::Value::ValueType arrayType = KisMetaData::Value::UnorderedArray;
                if (it->key() == "Exif.Photo.ISOSpeedRatings") {
                    forceSeq = true;
                    arrayType = KisMetaData::Value::OrderedArray;
                }
                v = exivValueToKMDValue(it->getValue(), forceSeq, arrayType);
            }
            if (it->key() == "Exif.Photo.InteroperabilityTag" || it->key() == "Exif.Photo.0xea1d") { // InteroperabilityTag isn't useful for XMP, 0xea1d isn't a valid Exif tag
                dbgFile << "Ignoring " << it->key().c_str();
            } else {
                store->addEntry(KisMetaData::Entry(exifSchema, it->tagName().c_str(), v));
            }
        } else if (it->groupName() == "Thumbnail") {
            dbgFile << "Ignoring thumbnail tag :" << it->key().c_str();
        } else {
            dbgFile << "Unknown exif tag, cannot load:" << it->key().c_str();
        }
    }
    ioDevice->close();
    return true;
}