bool getIptcString(Exiv2::IptcData &iptcData, const char *propertyName, bool isIptcUtf8, QString &resultValue) { bool anyFound = false; Exiv2::IptcKey key(propertyName); Exiv2::IptcData::iterator it = iptcData.findKey(key); if (it != iptcData.end()) { std::ostringstream os; os << *it; std::string str = os.str(); QString value; if (isIptcUtf8 || Helpers::isUtf8(str.c_str())) { value = QString::fromUtf8(str.c_str()).trimmed(); } else { value = QString::fromLocal8Bit(str.c_str()).trimmed(); } if (!value.isEmpty()) { resultValue = value; anyFound = true; } } return anyFound; }
// ***************************************************************************** // Main int main(int argc, char* const argv[]) try { if (argc != 2) { std::cout << "Usage: " << argv[0] << " file\n"; return 1; } Exiv2::IptcData iptcData; int rc = iptcData.read(argv[1]); if (rc) { std::string error = Exiv2::IptcData::strError(rc, argv[1]); throw Exiv2::Error(error); } Exiv2::IptcData::iterator end = iptcData.end(); for (Exiv2::IptcData::iterator i = iptcData.begin(); i != end; ++i) { std::cout << std::setw(40) << std::setfill(' ') << std::left << i->key() << " " << "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << i->tag() << " " << std::dec << i->value() << "\n"; } return rc; } catch (Exiv2::Error& e) { std::cout << "Caught Exiv2 exception '" << e << "'\n"; return -1; }
bool ImageTags::writeTagsToImage(QString &imageFileName, QSet<QString> &newTags) { QSet<QString> imageTags; Exiv2::Image::AutoPtr exifImage; try { exifImage = Exiv2::ImageFactory::open(imageFileName.toStdString()); exifImage->readMetadata(); Exiv2::IptcData newIptcData; /* copy existing data */ Exiv2::IptcData &iptcData = exifImage->iptcData(); if (!iptcData.empty()) { QString key; Exiv2::IptcData::iterator end = iptcData.end(); for (Exiv2::IptcData::iterator iptcIt = iptcData.begin(); iptcIt != end; ++iptcIt) { if (iptcIt->tagName() != "Keywords") { newIptcData.add(*iptcIt); } } } /* add new tags */ QSetIterator<QString> newTagsIt(newTags); while (newTagsIt.hasNext()) { QString tag = newTagsIt.next(); Exiv2::Value::AutoPtr value = Exiv2::Value::create(Exiv2::string); value->read(tag.toStdString()); Exiv2::IptcKey key("Iptc.Application2.Keywords"); newIptcData.add(key, value.get()); } exifImage->setIptcData(newIptcData); exifImage->writeMetadata(); } catch (Exiv2::Error &error) { QMessageBox msgBox; msgBox.critical(this, tr("Error"), tr("Failed to save tags to ") + imageFileName); return false; } return true; }
bool getIptcKeywords(Exiv2::IptcData &iptcData, bool isIptcUtf8, QStringList &keywords) { bool anyAdded = false; try { QString keywordsTagName = QString::fromLatin1(IPTC_KEYWORDS); for (Exiv2::IptcData::iterator it = iptcData.begin(); it != iptcData.end(); ++it) { QString key = QString::fromLocal8Bit(it->key().c_str()); if (key == keywordsTagName) { QString tag; if (isIptcUtf8) { tag = QString::fromUtf8(it->toString().c_str()); } else { tag = QString::fromLocal8Bit(it->toString().c_str()); } keywords.append(tag); anyAdded = true; } } if (keywords.length() == 1 && keywords[0].contains(',')) { LOG_DEBUG << "processing legacy saved keywords"; QString composite = keywords[0]; keywords.clear(); keywords += decomposeKeyword(composite); } } catch (Exiv2::Error &e) { LOG_WARNING << "Exiv2 error:" << e.what(); anyAdded = false; } catch (...) { LOG_WARNING << "Exception"; anyAdded = false; #ifdef QT_DEBUG throw; #endif } return anyAdded; }
QString getIptcCharset(Exiv2::IptcData &iptcData) { QString iptcCharset = ""; try { const char *charsetPtr = iptcData.detectCharset(); if (charsetPtr != NULL) { iptcCharset = QString::fromLatin1(charsetPtr).toUpper(); } } catch (Exiv2::Error &e) { LOG_WARNING << "Exiv2 error:" << e.what(); } return iptcCharset; }
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; }
KExiv2::MetaDataMap KExiv2::getIptcTagsDataList(const QStringList& iptcKeysFilter, bool invertSelection) const { if (d->iptcMetadata().empty()) return MetaDataMap(); try { Exiv2::IptcData iptcData = d->iptcMetadata(); iptcData.sortByKey(); QString ifDItemName; MetaDataMap metaDataMap; for (Exiv2::IptcData::iterator md = iptcData.begin(); md != iptcData.end(); ++md) { QString key = QString::fromLocal8Bit(md->key().c_str()); // Decode the tag value with a user friendly output. std::ostringstream os; os << *md; QString value = QString(os.str().c_str()); // To make a string just on one line. value.replace('\n', ' '); // Some Iptc key are redondancy. check if already one exist... MetaDataMap::iterator it = metaDataMap.find(key); // We apply a filter to get only the Iptc tags that we need. if (!invertSelection) { if (iptcKeysFilter.contains(key.section('.', 1, 1))) { if (it == metaDataMap.end()) metaDataMap.insert(key, value); else { QString v = *it; v.append(", "); v.append(value); metaDataMap.insert(key, v); } } } else { if (!iptcKeysFilter.contains(key.section('.', 1, 1))) { if (it == metaDataMap.end()) metaDataMap.insert(key, value); else { QString v = *it; v.append(", "); v.append(value); metaDataMap.insert(key, v); } } } } return metaDataMap; } catch (Exiv2::Error& e) { d->printExiv2ExceptionError("Cannot parse Iptc metadata using Exiv2 ", e); } return MetaDataMap(); }