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 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; }