void ImagePropertiesGPSTab::setMetadata(const DMetadata& meta, const KUrl& url) { double lat, lng; const bool haveCoordinates = meta.getGPSLatitudeNumber(&lat) && meta.getGPSLongitudeNumber(&lng); if (haveCoordinates) { double alt; const bool haveAlt = meta.getGPSAltitude(&alt); KGeoMap::GeoCoordinates coordinates(lat, lng); if (haveAlt) { coordinates.setAlt(alt); } GPSImageInfo gpsInfo; gpsInfo.coordinates = coordinates; gpsInfo.dateTime = meta.getImageDateTime(); gpsInfo.rating = meta.getImageRating(); gpsInfo.url = url; setGPSInfoList(GPSImageInfo::List() << gpsInfo); } else { clearGPSInfo(); } }
void TagsReadWriteTest::testTagSeparatorWrite() { DMetadata dmeta; DMetadataSettingsContainer dmsettings; QStringList readResult; QStringList expected; NamespaceEntry tagNs3; tagNs3.namespaceName = QLatin1String("Xmp.lr.hierarchicalSubject"); tagNs3.tagPaths = NamespaceEntry::TAGPATH; tagNs3.separator = QLatin1Char('|'); tagNs3.nsType = NamespaceEntry::TAGS; tagNs3.index = 2; tagNs3.specialOpts = NamespaceEntry::TAG_XMPBAG; tagNs3.subspace = NamespaceEntry::XMP; tagNs3.alternativeName = QLatin1String("Xmp.lr.HierarchicalSubject"); tagNs3.secondNameOpts = NamespaceEntry::TAG_XMPSEQ; dmsettings.getWriteMapping(QString::fromUtf8(DM_TAG_CONTAINER)).clear(); dmsettings.getWriteMapping(QString::fromUtf8(DM_TAG_CONTAINER)) << tagNs3; dmeta.setItemTagsPath(tagSet1, dmsettings); readResult = dmeta.getXmpTagStringBag("Xmp.lr.hierarchicalSubject", false); expected = tagSet1; expected = expected.replaceInStrings(QLatin1String("/"), QLatin1String("|")); QCOMPARE(readResult, expected); }
bool MetadataHub::write(DImg& image, WriteComponent writeMode, bool ignoreLazySync, const MetadataSettingsContainer& settings) { applyChangeNotifications(); // if no DMetadata object is needed at all, don't construct one if (!willWriteMetadata(writeMode, settings)) { return false; } // See DImgLoader::readMetadata() and saveMetadata() DMetadata metadata; metadata.setData(image.getMetadata()); QString filePath = image.originalFilePath(); if (filePath.isEmpty()) { filePath = image.lastSavedFilePath(); } if (!ignoreLazySync && settings.useLazySync && !filePath.isEmpty()) { ImageInfo info = ImageInfo::fromLocalFile(filePath); MetadataHubMngr::instance()->addPending(info); return true; } if (!filePath.isEmpty()) { writeToBaloo(filePath); } return write(metadata, writeMode, settings); }
int main (int /*argc*/, char** /*argv*/) { DMetadata meta; qDebug() << "-- Standard Exif Tags -------------------------------------------------------------"; DMetadata::TagsMap exiftags = meta.getStdExifTagsList(); for (DMetadata::TagsMap::const_iterator it = exiftags.constBegin(); it != exiftags.constEnd(); ++it ) { QString key = it.key(); QStringList values = it.value(); QString name = values[0]; QString title = values[1]; QString desc = values[2]; qDebug() << key << " :: " << name << " :: " << title << " :: " << desc; } qDebug() << "-- Makernote Tags -----------------------------------------------------------------"; DMetadata::TagsMap mntags = meta.getMakernoteTagsList(); for (DMetadata::TagsMap::const_iterator it = mntags.constBegin(); it != mntags.constEnd(); ++it ) { QString key = it.key(); QStringList values = it.value(); QString name = values[0]; QString title = values[1]; QString desc = values[2]; qDebug() << key << " :: " << name << " :: " << title << " :: " << desc; } qDebug() << "-- Standard Iptc Tags -----------------------------------------------------------------"; DMetadata::TagsMap iptctags = meta.getIptcTagsList(); for (DMetadata::TagsMap::const_iterator it = iptctags.constBegin(); it != iptctags.constEnd(); ++it ) { QString key = it.key(); QStringList values = it.value(); QString name = values[0]; QString title = values[1]; QString desc = values[2]; qDebug() << key << " :: " << name << " :: " << title << " :: " << desc; } qDebug() << "-- Standard Xmp Tags -----------------------------------------------------------------"; DMetadata::TagsMap xmptags = meta.getXmpTagsList(); for (DMetadata::TagsMap::const_iterator it = xmptags.constBegin(); it != xmptags.constEnd(); ++it ) { QString key = it.key(); QStringList values = it.value(); QString name = values[0]; QString title = values[1]; QString desc = values[2]; qDebug() << key << " :: " << name << " :: " << title << " :: " << desc; } return 0; }
void TagsReadWriteTest::testSimpleReadAfterWrite() { DMetadata dmeta; QStringList tagPaths2; dmeta.setItemTagsPath(this->tagSet1); dmeta.getItemTagsPath(tagPaths2); QCOMPARE(tagSet1, tagPaths2); }
QString MakerNoteWidget::getTagTitle(const QString& key) { DMetadata metadataIface; QString title = metadataIface.getExifTagTitle(key.toLatin1().constData()); if (title.isEmpty()) { return key.section(QLatin1Char('.'), -1); } return title; }
QString MakerNoteWidget::getTagDescription(const QString& key) { DMetadata metadataIface; QString desc = metadataIface.getExifTagDescription(key.toLatin1().constData()); if (desc.isEmpty()) { return i18n("No description available"); } return desc; }
/** * @brief Gets the coordinates of a marker found at current model index. * @param index Current model index. * @param coordinates Here will be returned the coordinates of the current marker. * @return True, if the marker has coordinates. */ bool MapViewModelHelper::itemCoordinates(const QModelIndex& index, GeoIface::GeoCoordinates* const coordinates) const { switch (d->application) { case MapWidgetView::ApplicationDigikam: { const ImageInfo info = d->model->imageInfo(index); if (info.isNull() || !info.hasCoordinates()) { return false; } *coordinates = GeoIface::GeoCoordinates(info.latitudeNumber(), info.longitudeNumber()); break; } case MapWidgetView::ApplicationImportUI: { const CamItemInfo info = d->importModel->camItemInfo(index); if (info.isNull()) { return false; } const DMetadata meta(info.url().toLocalFile()); double lat, lng; const bool haveCoordinates = meta.getGPSLatitudeNumber(&lat) && meta.getGPSLongitudeNumber(&lng); if (!haveCoordinates) { return false; } GeoIface::GeoCoordinates tmpCoordinates(lat, lng); double alt; const bool haveAlt = meta.getGPSAltitude(&alt); if (haveAlt) { tmpCoordinates.setAlt(alt); } *coordinates = tmpCoordinates; break; } } return true; }
bool MakerNoteWidget::decodeMetadata() { DMetadata data = getMetadata(); if (!data.hasExif()) { return false; } // Update all metadata contents. setMetadataMap(data.getExifTagsDataList(m_keysFilter, true)); return true; }
void IPTCEditWidget::slotItemChanged() { d->page_content->setHeader(d->dlg->currentItemTitleHeader(i18n("<qt>Content Information<br/>" "<i>Use this panel to describe the visual content of the image</i></qt>"))); d->page_origin->setHeader(d->dlg->currentItemTitleHeader(i18n("<qt>Origin Information<br/>" "<i>Use this panel for formal descriptive information about the image</i></qt>"))); d->page_credits->setHeader(d->dlg->currentItemTitleHeader(i18n("<qt>Credit Information<br/>" "<i>Use this panel to record copyright information about the image</i></qt>"))); d->page_subjects->setHeader(d->dlg->currentItemTitleHeader(i18n("<qt>Subject Information<br/>" "<i>Use this panel to record subject information about the image</i></qt>"))); d->page_keywords->setHeader(d->dlg->currentItemTitleHeader(i18n("<qt>Keyword Information<br/>" "<i>Use this panel to record keywords relevant to the image</i></qt>"))); d->page_categories->setHeader(d->dlg->currentItemTitleHeader(i18n("<qt>Category Information<br/>" "<i>Use this panel to record categories relevant to the image</i></qt>"))); d->page_status->setHeader(d->dlg->currentItemTitleHeader(i18n("<qt>Status Information<br/>" "<i>Use this panel to record workflow information</i></qt>"))); d->page_properties->setHeader(d->dlg->currentItemTitleHeader(i18n("<qt>Status Properties<br/>" "<i>Use this panel to record workflow properties</i></qt>"))); d->page_envelope->setHeader(d->dlg->currentItemTitleHeader(i18n("<qt>Envelope Information<br/>" "<i>Use this panel to record editorial details</i></qt>"))); DMetadata meta; meta.load((*d->dlg->currentItem()).path()); d->exifData = meta.getExifEncoded(); d->iptcData = meta.getIptc(); d->contentPage->readMetadata(d->iptcData); d->originPage->readMetadata(d->iptcData); d->creditsPage->readMetadata(d->iptcData); d->subjectsPage->readMetadata(d->iptcData); d->keywordsPage->readMetadata(d->iptcData); d->categoriesPage->readMetadata(d->iptcData); d->statusPage->readMetadata(d->iptcData); d->propertiesPage->readMetadata(d->iptcData); d->envelopePage->readMetadata(d->iptcData); d->isReadOnly = !DMetadata::canWriteIptc((*d->dlg->currentItem()).path()); emit signalSetReadOnly(d->isReadOnly); d->page_content->setEnabled(!d->isReadOnly); d->page_origin->setEnabled(!d->isReadOnly); d->page_credits->setEnabled(!d->isReadOnly); d->page_subjects->setEnabled(!d->isReadOnly); d->page_keywords->setEnabled(!d->isReadOnly); d->page_categories->setEnabled(!d->isReadOnly); d->page_status->setEnabled(!d->isReadOnly); d->page_properties->setEnabled(!d->isReadOnly); d->page_envelope->setEnabled(!d->isReadOnly); }
void XMPSubjects::applyMetadata(QByteArray& xmpData) { DMetadata meta; meta.setXmp(xmpData); QStringList newSubjects = subjectsList(); // We remove in first all existing subjects. meta.removeXmpTag("Xmp.iptc.SubjectCode"); // And add new list if necessary. if (m_subjectsCheck->isChecked()) meta.setXmpSubjects(newSubjects); xmpData = meta.getXmp(); }
bool AssignTemplate::toolOperations() { DMetadata meta; if (image().isNull()) { if (!meta.load(inputUrl().toLocalFile())) { return false; } } else { meta.setData(image().getMetadata()); } QString title = settings()[QLatin1String("TemplateTitle")].toString(); if (title == Template::removeTemplateTitle()) { meta.removeMetadataTemplate(); } else if (title.isEmpty()) { // Nothing to do. } else { Template t = TemplateManager::defaultManager()->findByTitle(title); meta.removeMetadataTemplate(); meta.setMetadataTemplate(t); } bool ret = true; if (image().isNull()) { QFile::remove(outputUrl().toLocalFile()); ret = QFile::copy(inputUrl().toLocalFile(), outputUrl().toLocalFile()); if (ret && !title.isEmpty()) { ret = meta.save(outputUrl().toLocalFile()); } } else { if (!title.isEmpty()) { image().setMetadata(meta.data()); } ret = savefromDImg(); } return ret; }
void TagsReadWriteTest::testWriteToDisabledNamespaces() { DMetadata dmeta; DMetadataSettingsContainer dmsettings; QStringList empty; QStringList secondNamespace; NamespaceEntry tagNs2; tagNs2.namespaceName = QLatin1String("Xmp.MicrosoftPhoto.LastKeywordXMP"); tagNs2.tagPaths = NamespaceEntry::TAGPATH; tagNs2.separator = QLatin1Char('/'); tagNs2.nsType = NamespaceEntry::TAGS; tagNs2.index = 1; tagNs2.specialOpts = NamespaceEntry::TAG_XMPBAG; tagNs2.subspace = NamespaceEntry::XMP; tagNs2.isDisabled = true; NamespaceEntry tagNs3; tagNs3.namespaceName = QLatin1String("Xmp.lr.hierarchicalSubject"); tagNs3.tagPaths = NamespaceEntry::TAGPATH; tagNs3.separator = QLatin1Char('|'); tagNs3.nsType = NamespaceEntry::TAGS; tagNs3.index = 2; tagNs3.specialOpts = NamespaceEntry::TAG_XMPBAG; tagNs3.subspace = NamespaceEntry::XMP; tagNs3.alternativeName = QLatin1String("Xmp.lr.HierarchicalSubject"); tagNs3.secondNameOpts = NamespaceEntry::TAG_XMPSEQ; dmsettings.getWriteMapping(QString::fromUtf8(DM_TAG_CONTAINER)).clear(); dmsettings.getWriteMapping(QString::fromUtf8(DM_TAG_CONTAINER)) << tagNs2 << tagNs3; dmeta.setItemTagsPath(tagSet1, dmsettings); empty = dmeta.getXmpTagStringBag("Xmp.MicrosoftPhoto.LastKeywordXMP", false); QCOMPARE(empty, QStringList()); secondNamespace = dmeta.getXmpTagStringBag("Xmp.lr.hierarchicalSubject", false); secondNamespace = secondNamespace.replaceInStrings(QLatin1String("|"), QLatin1String("/")); QCOMPARE(secondNamespace, tagSet1); }
void CommentReadWriteTest::testSimpleReadAfterWrite() { DMetadata dmeta; CaptionsMap result; // Trick dmetadata, so it will think that we have a file path dmeta.setFilePath(QLatin1String("random.org")); dmeta.setItemComments(commentSet1); result = dmeta.getItemComments(); QString rezAuthor = result.value(QLatin1String("x-default")).author; QString rezComment = result.value(QLatin1String("x-default")).caption; QCOMPARE(rezAuthor, commentSet1.value(QLatin1String("x-default")).author); QCOMPARE(rezComment, commentSet1.value(QLatin1String("x-default")).caption); }
MyImageData LoadImageData(const QUrl& urlToLoad) { MyImageData imageData; imageData.url = urlToLoad; // TODO: error handling! DMetadata meta; meta.load(urlToLoad.toLocalFile()); double lat, lon, alt; if (meta.getGPSInfo(alt, lat, lon)) { imageData.coordinates.setLatLon(lat, lon); imageData.coordinates.setAlt(alt); } return imageData; }
void CommentReadWriteTest::testWriteToDisabledNamespaces() { DMetadata dmeta; dmeta.setFilePath(QLatin1String("random.org")); MetaEngine::AltLangMap commentsMap; QString commentString; DMetadataSettingsContainer dmsettings; NamespaceEntry commNs1; commNs1.namespaceName = QLatin1String("Xmp.dc.description"); commNs1.nsType = NamespaceEntry::COMMENT; commNs1.specialOpts = NamespaceEntry::COMMENT_ATLLANGLIST; commNs1.index = 0; commNs1.subspace = NamespaceEntry::XMP; commNs1.isDisabled = true; NamespaceEntry commNs2; commNs2.namespaceName = QLatin1String("Xmp.exif.UserComment"); commNs2.nsType = NamespaceEntry::COMMENT; commNs2.specialOpts = NamespaceEntry::COMMENT_ALTLANG; commNs2.index = 1; commNs2.subspace = NamespaceEntry::XMP; dmsettings.setUnifyReadWrite(false); dmsettings.getWriteMapping(QString::fromUtf8(DM_COMMENT_CONTAINER)).clear(); dmsettings.getWriteMapping(QString::fromUtf8(DM_COMMENT_CONTAINER)) << commNs1 << commNs2; bool rez = dmeta.setItemComments(commentSet1, dmsettings); QVERIFY(rez); commentsMap = dmeta.getXmpTagStringListLangAlt("Xmp.dc.description", false); QCOMPARE(commentsMap.value(QLatin1String("x-default")), QString()); commentString = dmeta.getXmpTagStringLangAlt("Xmp.exif.UserComment", QString(), false); QCOMPARE(commentString, commentSet1.value(QLatin1String("x-default")).caption); }
void IPTCKeywords::applyMetadata(QByteArray& iptcData) { DMetadata meta; meta.setIptc(iptcData); QStringList newKeywords; for (int i = 0 ; i < d->keywordsBox->count(); ++i) { QListWidgetItem* const item = d->keywordsBox->item(i); newKeywords.append(item->text()); } if (d->keywordsCheck->isChecked()) meta.setIptcKeywords(d->oldKeywords, newKeywords); else meta.setIptcKeywords(d->oldKeywords, QStringList()); iptcData = meta.getIptc(); }
void TagsReadWriteTest::testReadFromDisabledNamespaces() { DMetadata dmeta; DMetadataSettingsContainer dmsettings; QStringList actual; NamespaceEntry tagNs2; tagNs2.namespaceName = QLatin1String("Xmp.MicrosoftPhoto.LastKeywordXMP"); tagNs2.tagPaths = NamespaceEntry::TAGPATH; tagNs2.separator = QLatin1String("/"); tagNs2.nsType = NamespaceEntry::TAGS; tagNs2.index = 1; tagNs2.specialOpts = NamespaceEntry::TAG_XMPBAG; tagNs2.subspace = NamespaceEntry::XMP; tagNs2.isDisabled = true; NamespaceEntry tagNs3; tagNs3.namespaceName = QLatin1String("Xmp.lr.hierarchicalSubject"); tagNs3.tagPaths = NamespaceEntry::TAGPATH; tagNs3.separator = QLatin1String("|"); tagNs3.nsType = NamespaceEntry::TAGS; tagNs3.index = 2; tagNs3.specialOpts = NamespaceEntry::TAG_XMPBAG; tagNs3.subspace = NamespaceEntry::XMP; tagNs3.alternativeName = QLatin1String("Xmp.lr.HierarchicalSubject"); tagNs3.secondNameOpts = NamespaceEntry::TAG_XMPSEQ; dmsettings.getReadMapping(QLatin1String(DM_TAG_CONTAINER)).clear(); dmsettings.getReadMapping(QLatin1String(DM_TAG_CONTAINER)) << tagNs2 << tagNs3; dmeta.setXmpTagStringBag("Xmp.MicrosoftPhoto.LastKeywordXMP", tagSet1); dmeta.setXmpTagStringBag("Xmp.lr.hierarchicalSubject", tagSet2); dmeta.getImageTagsPath(actual, dmsettings); QCOMPARE(actual, tagSet2); }
void TagsReadWriteTest::testTagReadAlternativeNameSpace() { DMetadata dmeta; DMetadataSettingsContainer dmsettings; QStringList toWrite; QStringList actual; QStringList reference; NamespaceEntry tagNs3; tagNs3.namespaceName = QLatin1String("Xmp.lr.hierarchicalSubject"); tagNs3.tagPaths = NamespaceEntry::TAGPATH; tagNs3.separator = QLatin1Char('|'); tagNs3.nsType = NamespaceEntry::TAGS; tagNs3.index = 2; tagNs3.specialOpts = NamespaceEntry::TAG_XMPBAG; tagNs3.subspace = NamespaceEntry::XMP; tagNs3.alternativeName = QLatin1String("Xmp.lr.HierarchicalSubject"); tagNs3.secondNameOpts = NamespaceEntry::TAG_XMPSEQ; dmsettings.getReadMapping(QString::fromUtf8(DM_TAG_CONTAINER)).clear(); dmsettings.getReadMapping(QString::fromUtf8(DM_TAG_CONTAINER)) << tagNs3; toWrite = tagSet1; toWrite = toWrite.replaceInStrings(QLatin1String("/"), QLatin1String("|")); dmeta.setXmpTagStringSeq("Xmp.lr.HierarchicalSubject", toWrite); // We write some data to alternative namespace reference = dmeta.getXmpTagStringSeq("Xmp.lr.HierarchicalSubject", false); QCOMPARE(reference, toWrite); dmeta.getItemTagsPath(actual, dmsettings); QCOMPARE(actual, tagSet1); }
void IPTCEditWidget::apply() { if (d->modified && !d->isReadOnly) { d->contentPage->applyMetadata(d->exifData, d->iptcData); d->originPage->applyMetadata(d->exifData, d->iptcData); d->creditsPage->applyMetadata(d->iptcData); d->subjectsPage->applyMetadata(d->iptcData); d->keywordsPage->applyMetadata(d->iptcData); d->categoriesPage->applyMetadata(d->iptcData); d->statusPage->applyMetadata(d->iptcData); d->propertiesPage->applyMetadata(d->iptcData); d->envelopePage->applyMetadata(d->iptcData); DMetadata meta; meta.load((*d->dlg->currentItem()).path()); meta.setExif(d->exifData); meta.setIptc(d->iptcData); meta.save((*d->dlg->currentItem()).path()); d->modified = false; } }
void IPTCKeywords::readMetadata(QByteArray& iptcData) { blockSignals(true); DMetadata meta; meta.setIptc(iptcData); d->oldKeywords = meta.getIptcKeywords(); d->keywordsBox->clear(); d->keywordsCheck->setChecked(false); if (!d->oldKeywords.isEmpty()) { d->keywordsBox->insertItems(0, d->oldKeywords); d->keywordsCheck->setChecked(true); } d->keywordEdit->setEnabled(d->keywordsCheck->isChecked()); d->keywordsBox->setEnabled(d->keywordsCheck->isChecked()); d->addKeywordButton->setEnabled(d->keywordsCheck->isChecked()); d->delKeywordButton->setEnabled(d->keywordsCheck->isChecked()); blockSignals(false); }
void IPTCSubjects::applyMetadata(QByteArray& iptcData) { DMetadata meta; meta.setIptc(iptcData); QStringList newSubjects = subjectsList(); if (m_subjectsCheck->isChecked()) meta.setIptcSubjects(meta.getIptcSubjects(), newSubjects); else meta.setIptcSubjects(meta.getIptcSubjects(), QStringList()); iptcData = meta.getIptc(); }
void CommentReadWriteTest::testReadFromDisabledNamespaces() { DMetadata dmeta; dmeta.setFilePath(QLatin1String("random.org")); CaptionsMap rez; DMetadataSettingsContainer dmsettings; NamespaceEntry commNs1; commNs1.namespaceName = QLatin1String("Xmp.dc.description"); commNs1.nsType = NamespaceEntry::COMMENT; commNs1.specialOpts = NamespaceEntry::COMMENT_ATLLANGLIST; commNs1.index = 0; commNs1.subspace = NamespaceEntry::XMP; commNs1.isDisabled = true; NamespaceEntry commNs2; commNs2.namespaceName = QLatin1String("Xmp.exif.UserComment"); commNs2.nsType = NamespaceEntry::COMMENT; commNs2.specialOpts = NamespaceEntry::COMMENT_ALTLANG; commNs2.index = 1; commNs2.subspace = NamespaceEntry::XMP; dmsettings.setUnifyReadWrite(false); dmsettings.getReadMapping(QString::fromUtf8(DM_COMMENT_CONTAINER)).clear(); dmsettings.getReadMapping(QString::fromUtf8(DM_COMMENT_CONTAINER)) << commNs1 << commNs2; dmeta.setXmpTagStringListLangAlt("Xmp.dc.description", commentSet1.toAltLangMap()); dmeta.setXmpTagStringLangAlt("Xmp.exif.UserComment", commentSet2.value(QLatin1String("x-default")).caption, QString()); rez = dmeta.getItemComments(dmsettings); QCOMPARE(rez.value(QLatin1String("x-default")).caption, commentSet2.value(QLatin1String("x-default")).caption); }
int LoadSaveThread::exifOrientation(const QString& filePath, const DMetadata& metadata, bool isRaw, bool fromRawEmbeddedPreview) { int dbOrientation = KExiv2::ORIENTATION_UNSPECIFIED; if (infoProvider()) { dbOrientation = infoProvider()->orientationHint(filePath); } int exifOrientation = metadata.getImageOrientation(); // Raw files are already rotated properly by dcraw. Only perform auto-rotation with JPEG/PNG/TIFF file. // We don't have a feedback from dcraw about auto-rotated RAW file during decoding. if (isRaw && !fromRawEmbeddedPreview) { // Did the user apply any additional rotation over the metadata flag? if (dbOrientation == KExiv2::ORIENTATION_UNSPECIFIED || dbOrientation == exifOrientation) { return KExiv2::ORIENTATION_NORMAL; } // Assume A is the orientation as from metadata, B is an additional operation applied by the user, // C is the current orientation in the database. // A*B = C and B = A_inv * C QMatrix A = KExiv2Iface::RotationMatrix::toMatrix((KExiv2::ImageOrientation)exifOrientation); QMatrix C = KExiv2Iface::RotationMatrix::toMatrix((KExiv2::ImageOrientation)dbOrientation); QMatrix A_inv = A.inverted(); QMatrix B = A_inv * C; RotationMatrix m(B.m11(), B.m12(), B.m21(), B.m22()); return m.exifOrientation(); } if (dbOrientation != KExiv2::ORIENTATION_UNSPECIFIED) { return dbOrientation; } return exifOrientation; }
void ShowFoto::openUrls(const QList<QUrl> &urls) { if (!urls.isEmpty()) { ShowfotoItemInfoList infos; ShowfotoItemInfo iteminfo; DMetadata meta; for (QList<QUrl>::const_iterator it = urls.constBegin(); it != urls.constEnd(); ++it) { QFileInfo fi((*it).toLocalFile()); iteminfo.name = fi.fileName(); iteminfo.mime = fi.suffix(); iteminfo.size = fi.size(); iteminfo.url = QUrl::fromLocalFile(fi.filePath()); iteminfo.folder = fi.path(); iteminfo.dtime = fi.created(); meta.load(fi.filePath()); iteminfo.ctime = meta.getImageDateTime(); iteminfo.width = meta.getImageDimensions().width(); iteminfo.height = meta.getImageDimensions().height(); iteminfo.photoInfo = meta.getPhotographInformation(); infos.append(iteminfo); } if (d->droppedUrls) { //replace the equal sign with "<<" to keep the previous pics in the list d->infoList << infos; } else { d->infoList = infos; d->model->clearShowfotoItemInfos(); emit signalInfoList(d->infoList); slotOpenUrl(d->thumbBar->currentInfo()); } } }
/** * @brief This function finds the best representative marker from a group of markers. This is needed to display a thumbnail for a marker group. * @param indices A list containing markers. * @param sortKey Determines the sorting options and is actually of type GPSImageInfoSorter::SortOptions * @return Returns the index of the marker. */ QPersistentModelIndex MapViewModelHelper::bestRepresentativeIndexFromList(const QList<QPersistentModelIndex>& list, const int sortKey) { if (list.isEmpty()) { return QPersistentModelIndex(); } // first convert from QPersistentModelIndex to QModelIndex QList<QModelIndex> indexList; QModelIndex bestIndex; for (int i=0; i < list.count(); ++i) { const QModelIndex newIndex(list.at(i)); indexList.append(newIndex); } switch (d->application) { case MapWidgetView::ApplicationDigikam: { // now get the ImageInfos and convert them to GPSImageInfos const QList<ImageInfo> imageInfoList = d->model->imageInfos(indexList); GPSImageInfo::List gpsImageInfoList; foreach(const ImageInfo& imageInfo, imageInfoList) { GPSImageInfo gpsImageInfo; if (ImagePropertiesSideBarDB::GPSImageInfofromImageInfo(imageInfo, &gpsImageInfo)) { gpsImageInfoList << gpsImageInfo; } } if (gpsImageInfoList.size()!=indexList.size()) { // this is a problem, and unexpected return indexList.first(); } // now determine the best available index bestIndex = indexList.first(); GPSImageInfo bestGPSImageInfo = gpsImageInfoList.first(); for (int i=1; i < gpsImageInfoList.count(); ++i) { const GPSImageInfo& currentInfo = gpsImageInfoList.at(i); if (GPSImageInfoSorter::fitsBetter(bestGPSImageInfo, GeoIface::SelectedNone, currentInfo, GeoIface::SelectedNone, GeoIface::SelectedNone, GPSImageInfoSorter::SortOptions(sortKey))) { bestIndex = indexList.at(i); bestGPSImageInfo = currentInfo; } } break; } case MapWidgetView::ApplicationImportUI: { // now get the CamItemInfo and convert them to GPSImageInfos const QList<CamItemInfo> imageInfoList = d->importModel->camItemInfos(indexList); GPSImageInfo::List gpsImageInfoList; foreach(const CamItemInfo& imageInfo, imageInfoList) { const DMetadata meta(imageInfo.url().toLocalFile()); double lat, lng; const bool hasCoordinates = meta.getGPSLatitudeNumber(&lat) && meta.getGPSLongitudeNumber(&lng); if (!hasCoordinates) { continue; } GeoIface::GeoCoordinates coordinates(lat, lng); double alt; const bool haveAlt = meta.getGPSAltitude(&alt); if (haveAlt) { coordinates.setAlt(alt); } GPSImageInfo gpsImageInfo; gpsImageInfo.coordinates = coordinates; gpsImageInfo.dateTime = meta.getImageDateTime(); gpsImageInfo.rating = meta.getImageRating(); gpsImageInfo.url = imageInfo.url(); gpsImageInfoList << gpsImageInfo; } if (gpsImageInfoList.size()!=indexList.size()) { // this is a problem, and unexpected return indexList.first(); } // now determine the best available index bestIndex = indexList.first(); GPSImageInfo bestGPSImageInfo = gpsImageInfoList.first(); for (int i=1; i < gpsImageInfoList.count(); ++i) { const GPSImageInfo& currentInfo = gpsImageInfoList.at(i); if (GPSImageInfoSorter::fitsBetter(bestGPSImageInfo, GeoIface::SelectedNone, currentInfo, GeoIface::SelectedNone, GeoIface::SelectedNone, GPSImageInfoSorter::SortOptions(sortKey))) { bestIndex = indexList.at(i); bestGPSImageInfo = currentInfo; } } break; } }
bool GPCamera::getMetadata(const QString& folder, const QString& itemName, DMetadata& meta) { #ifdef HAVE_GPHOTO2 int errorCode; CameraFile* cfile = 0; const char* data = 0; unsigned long int size; gp_file_new(&cfile); d->status->cancel = false; errorCode = gp_camera_file_get(d->camera, QFile::encodeName(folder).constData(), QFile::encodeName(itemName).constData(), GP_FILE_TYPE_EXIF, cfile, d->status->context); if (errorCode != GP_OK) { qCDebug(DIGIKAM_IMPORTUI_LOG) << "Failed to get camera item!"; printGphotoErrorDescription(errorCode); gp_file_unref(cfile); return false; } errorCode = gp_file_get_data_and_size(cfile, &data, &size); if (errorCode != GP_OK) { qCDebug(DIGIKAM_IMPORTUI_LOG) << "Failed to get Exif data from camera item!"; printGphotoErrorDescription(errorCode); gp_file_unref(cfile); return false; } QByteArray exifData(data, size); gp_file_unref(cfile); // Sometimes, GPhoto2 drivers return complete APP1 JFIF section. Exiv2 cannot // decode (yet) exif metadata from APP1. We will find Exif header to get data at this place // to please with Exiv2... qCDebug(DIGIKAM_IMPORTUI_LOG) << "Size of Exif metadata from camera = " << exifData.size(); if (!exifData.isEmpty()) { char exifHeader[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; int i = exifData.indexOf(*exifHeader); if (i != -1) { qCDebug(DIGIKAM_IMPORTUI_LOG) << "Exif header found at position " << i; i = i + sizeof(exifHeader); QByteArray data; data.resize(exifData.size() - i); memcpy(data.data(), exifData.data() + i, data.size()); meta.setExif(data); return true; } } return false; #else Q_UNUSED(folder); Q_UNUSED(itemName); Q_UNUSED(meta); return false; #endif /* HAVE_GPHOTO2 */ }
void TimeAdjustTask::run() { if (m_cancel) return; emit signalProcessStarted(d->url); QDateTime dt = d->itemsMap.value(d->url); if (!dt.isValid()) { emit signalProcessEnded(d->url, TimeAdjustList::META_TIME_ERROR); emit signalDone(); return; } bool writeToSidecar = (MetaEngineSettings::instance()->settings() .metadataWritingMode != DMetadata::WRITE_TO_FILE_ONLY); bool metadataChanged = d->settings.updEXIFModDate || d->settings.updEXIFOriDate || d->settings.updEXIFDigDate || d->settings.updEXIFThmDate || d->settings.updIPTCDate || d->settings.updXMPVideo || d->settings.updXMPDate; int status = TimeAdjustList::NOPROCESS_ERROR; if (metadataChanged) { bool ret = true; DMetadata meta; ret &= meta.load(d->url.toLocalFile()); if (ret) { QString exifDateTimeFormat = QLatin1String("yyyy:MM:dd hh:mm:ss"); QString xmpDateTimeFormat = QLatin1String("yyyy:MM:ddThh:mm:ss"); if (writeToSidecar || meta.canWriteExif(d->url.toLocalFile())) { if (d->settings.updEXIFModDate) { if (!d->settings.updIfAvailable || !meta.getExifTagString("Exif.Image.DateTime").isEmpty()) { ret &= meta.setExifTagString("Exif.Image.DateTime", dt.toString(exifDateTimeFormat)); } } if (d->settings.updEXIFOriDate) { if (!d->settings.updIfAvailable || !meta.getExifTagString("Exif.Photo.DateTimeOriginal").isEmpty()) { ret &= meta.setExifTagString("Exif.Photo.DateTimeOriginal", dt.toString(exifDateTimeFormat)); } } if (d->settings.updEXIFDigDate) { if (!d->settings.updIfAvailable || !meta.getExifTagString("Exif.Photo.DateTimeDigitized").isEmpty()) { ret &= meta.setExifTagString("Exif.Photo.DateTimeDigitized", dt.toString(exifDateTimeFormat)); } } if (d->settings.updEXIFThmDate) { if (!d->settings.updIfAvailable || !meta.getExifTagString("Exif.Image.PreviewDateTime").isEmpty()) { ret &= meta.setExifTagString("Exif.Image.PreviewDateTime", dt.toString(exifDateTimeFormat)); } } } else if (d->settings.updEXIFModDate || d->settings.updEXIFOriDate || d->settings.updEXIFDigDate || d->settings.updEXIFThmDate) { ret = false; } if (d->settings.updIPTCDate) { if (writeToSidecar || meta.canWriteIptc(d->url.toLocalFile())) { if (!d->settings.updIfAvailable || !meta.getIptcTagString("Iptc.Application2.DateCreated").isEmpty()) { ret &= meta.setIptcTagString("Iptc.Application2.DateCreated", dt.date().toString(Qt::ISODate)); } if (!d->settings.updIfAvailable || !meta.getIptcTagString("Iptc.Application2.TimeCreated").isEmpty()) { ret &= meta.setIptcTagString("Iptc.Application2.TimeCreated", dt.time().toString(Qt::ISODate)); } } else { ret = false; } } if (d->settings.updXMPDate) { if (writeToSidecar || (meta.supportXmp() && meta.canWriteXmp(d->url.toLocalFile()))) { if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.exif.DateTimeOriginal").isEmpty()) { ret &= meta.setXmpTagString("Xmp.exif.DateTimeOriginal", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.photoshop.DateCreated").isEmpty()) { ret &= meta.setXmpTagString("Xmp.photoshop.DateCreated", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.tiff.DateTime").isEmpty()) { ret &= meta.setXmpTagString("Xmp.tiff.DateTime", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.xmp.CreateDate").isEmpty()) { ret &= meta.setXmpTagString("Xmp.xmp.CreateDate", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.xmp.MetadataDate").isEmpty()) { ret &= meta.setXmpTagString("Xmp.xmp.MetadataDate", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.xmp.ModifyDate").isEmpty()) { ret &= meta.setXmpTagString("Xmp.xmp.ModifyDate", dt.toString(xmpDateTimeFormat)); } } else { ret = false; } } if (d->settings.updXMPVideo) { if (writeToSidecar || (meta.supportXmp() && meta.canWriteXmp(d->url.toLocalFile()))) { if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.video.DateTimeOriginal").isEmpty()) { ret &= meta.setXmpTagString("Xmp.video.DateTimeOriginal", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.video.DateTimeDigitized").isEmpty()) { ret &= meta.setXmpTagString("Xmp.video.DateTimeDigitized", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.video.ModificationDate").isEmpty()) { ret &= meta.setXmpTagString("Xmp.video.ModificationDate", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.video.DateUTC").isEmpty()) { ret &= meta.setXmpTagString("Xmp.video.DateUTC", dt.toUTC().toString(xmpDateTimeFormat)); } } else { ret = false; } } ret &= meta.save(d->url.toLocalFile()); if (!ret) { qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Failed to update metadata in file " << d->url.fileName(); } } else { qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Failed to load metadata from file " << d->url.fileName(); } if (!ret) { status |= TimeAdjustList::META_TIME_ERROR; } } if (d->settings.updFileModDate) { // Since QFileInfo does not support timestamp updates, // we have to use the utime() system call. int modtime; QDateTime unixDate; unixDate.setDate(QDate(1970, 1, 1)); unixDate.setTime(QTime(0, 0, 0, 0)); if (dt < unixDate) modtime = -(dt.secsTo(unixDate) + (60 * 60)); else modtime = dt.toTime_t(); struct utimbuf ut; ut.modtime = modtime; ut.actime = QDateTime::currentDateTime().toTime_t(); if (::utime(QFile::encodeName(d->url.toLocalFile()).constData(), &ut) != 0) { status |= TimeAdjustList::FILE_TIME_ERROR; } } if (writeToSidecar && DMetadata::hasSidecar(d->url.toLocalFile())) { QT_STATBUF st; if (QT_STAT(QFile::encodeName(d->url.toLocalFile()).constData(), &st) == 0) { struct utimbuf ut; ut.modtime = st.st_mtime; ut.actime = st.st_atime; if (::utime(QFile::encodeName(DMetadata::sidecarPath(d->url.toLocalFile())).constData(), &ut) != 0) { status |= TimeAdjustList::FILE_TIME_ERROR; } } } if (status == TimeAdjustList::NOPROCESS_ERROR) { emit signalDateTimeForUrl(d->url, dt, d->settings.updFileModDate); } emit signalProcessEnded(d->url, status); emit signalDone(); }
void CameraItemPropertiesTab::setCurrentItem(const CamItemInfo& itemInfo, const DMetadata& meta) { if (itemInfo.isNull()) { d->labelFile->setAdjustedText(QString()); d->labelFolder->setAdjustedText(QString()); d->labelFileIsReadable->setAdjustedText(QString()); d->labelFileIsWritable->setAdjustedText(QString()); d->labelFileDate->setAdjustedText(QString()); d->labelFileSize->setAdjustedText(QString()); d->labelImageMime->setAdjustedText(QString()); d->labelImageDimensions->setAdjustedText(QString()); d->labelImageRatio->setAdjustedText(QString()); d->labelNewFileName->setAdjustedText(QString()); d->labelAlreadyDownloaded->setAdjustedText(QString()); d->labelPhotoMake->setAdjustedText(QString()); d->labelPhotoModel->setAdjustedText(QString()); d->labelPhotoDateTime->setAdjustedText(QString()); d->labelPhotoLens->setAdjustedText(QString()); d->labelPhotoAperture->setAdjustedText(QString()); d->labelPhotoFocalLength->setAdjustedText(QString()); d->labelPhotoExposureTime->setAdjustedText(QString()); d->labelPhotoSensitivity->setAdjustedText(QString()); d->labelPhotoExposureMode->setAdjustedText(QString()); d->labelPhotoFlash->setAdjustedText(QString()); d->labelPhotoWhiteBalance->setAdjustedText(QString()); d->labelVideoAspectRatio->setAdjustedText(QString()); d->labelVideoAudioBitRate->setAdjustedText(QString()); d->labelVideoAudioChannelType->setAdjustedText(QString()); d->labelVideoAudioCompressor->setAdjustedText(QString()); d->labelVideoDuration->setAdjustedText(QString()); d->labelVideoFrameRate->setAdjustedText(QString()); d->labelVideoVideoCodec->setAdjustedText(QString()); setEnabled(false); return; } setEnabled(true); QString str; QString unknown(i18n("<i>unknown</i>")); // -- Camera file system information ------------------------------------------ d->labelFile->setAdjustedText(itemInfo.name); d->labelFolder->setAdjustedText(itemInfo.folder); if (itemInfo.readPermissions < 0) { str = unknown; } else if (itemInfo.readPermissions == 0) { str = i18n("No"); } else { str = i18n("Yes"); } d->labelFileIsReadable->setAdjustedText(str); if (itemInfo.writePermissions < 0) { str = unknown; } else if (itemInfo.writePermissions == 0) { str = i18n("No"); } else { str = i18n("Yes"); } d->labelFileIsWritable->setAdjustedText(str); if (itemInfo.ctime.isValid()) { d->labelFileDate->setAdjustedText(QLocale().toString(itemInfo.ctime, QLocale::ShortFormat)); } else { d->labelFileDate->setAdjustedText(unknown); } str = i18n("%1 (%2)", ImagePropertiesTab::humanReadableBytesCount(itemInfo.size), QLocale().toString(itemInfo.size)); d->labelFileSize->setAdjustedText(str); // -- Image Properties -------------------------------------------------- if (itemInfo.mime == QLatin1String("image/x-raw")) { d->labelImageMime->setAdjustedText(i18n("RAW Image")); } else { QMimeType mimeType = QMimeDatabase().mimeTypeForName(itemInfo.mime); if (mimeType.isValid()) { d->labelImageMime->setAdjustedText(mimeType.comment()); } else { d->labelImageMime->setAdjustedText(itemInfo.mime); // last fallback } } QString mpixels; QSize dims; if (itemInfo.width == -1 && itemInfo.height == -1) { // delayed loading to list faster from UMSCamera if (itemInfo.mime == QLatin1String("image/x-raw")) { dims = meta.getImageDimensions(); } else { dims = meta.getPixelSize(); } } else { // if available (GPCamera), take dimensions directly from itemInfo dims = QSize(itemInfo.width, itemInfo.height); } mpixels.setNum(dims.width()*dims.height()/1000000.0, 'f', 2); str = (!dims.isValid()) ? unknown : i18n("%1x%2 (%3Mpx)", dims.width(), dims.height(), mpixels); d->labelImageDimensions->setAdjustedText(str); if (!dims.isValid()) str = unknown; else ImagePropertiesTab::aspectRatioToString(dims.width(), dims.height(), str); d->labelImageRatio->setAdjustedText(str); // -- Download information ------------------------------------------ d->labelNewFileName->setAdjustedText(itemInfo.downloadName.isEmpty() ? i18n("<i>unchanged</i>") : itemInfo.downloadName); if (itemInfo.downloaded == CamItemInfo::DownloadUnknown) { str = unknown; } else if (itemInfo.downloaded == CamItemInfo::DownloadedYes) { str = i18n("Yes"); } else { str = i18n("No"); } d->labelAlreadyDownloaded->setAdjustedText(str); // -- Photograph information ------------------------------------------ // Note: If something is changed here, please updated albumfiletip section too. QString unavailable(i18n("<i>unavailable</i>")); PhotoInfoContainer photoInfo = meta.getPhotographInformation(); if (photoInfo.isEmpty()) { widget(1)->hide(); } else { widget(1)->show(); } ImagePropertiesTab::shortenedMakeInfo(photoInfo.make); ImagePropertiesTab::shortenedModelInfo(photoInfo.model); d->labelPhotoMake->setAdjustedText(photoInfo.make.isEmpty() ? unavailable : photoInfo.make); d->labelPhotoModel->setAdjustedText(photoInfo.model.isEmpty() ? unavailable : photoInfo.model); if (photoInfo.dateTime.isValid()) { str = QLocale().toString(photoInfo.dateTime, QLocale::ShortFormat); d->labelPhotoDateTime->setAdjustedText(str); } else { d->labelPhotoDateTime->setAdjustedText(unavailable); } d->labelPhotoLens->setAdjustedText(photoInfo.lens.isEmpty() ? unavailable : photoInfo.lens); d->labelPhotoAperture->setAdjustedText(photoInfo.aperture.isEmpty() ? unavailable : photoInfo.aperture); if (photoInfo.focalLength35mm.isEmpty()) { d->labelPhotoFocalLength->setAdjustedText(photoInfo.focalLength.isEmpty() ? unavailable : photoInfo.focalLength); } else { str = i18n("%1 (%2)", photoInfo.focalLength, photoInfo.focalLength35mm); d->labelPhotoFocalLength->setAdjustedText(str); } d->labelPhotoExposureTime->setAdjustedText(photoInfo.exposureTime.isEmpty() ? unavailable : photoInfo.exposureTime); d->labelPhotoSensitivity->setAdjustedText(photoInfo.sensitivity.isEmpty() ? unavailable : i18n("%1 ISO", photoInfo.sensitivity)); if (photoInfo.exposureMode.isEmpty() && photoInfo.exposureProgram.isEmpty()) { d->labelPhotoExposureMode->setAdjustedText(unavailable); } else if (!photoInfo.exposureMode.isEmpty() && photoInfo.exposureProgram.isEmpty()) { d->labelPhotoExposureMode->setAdjustedText(photoInfo.exposureMode); } else if (photoInfo.exposureMode.isEmpty() && !photoInfo.exposureProgram.isEmpty()) { d->labelPhotoExposureMode->setAdjustedText(photoInfo.exposureProgram); } else { str = QString::fromUtf8("%1 / %2").arg(photoInfo.exposureMode).arg(photoInfo.exposureProgram); d->labelPhotoExposureMode->setAdjustedText(str); } d->labelPhotoFlash->setAdjustedText(photoInfo.flash.isEmpty() ? unavailable : photoInfo.flash); d->labelPhotoWhiteBalance->setAdjustedText(photoInfo.whiteBalance.isEmpty() ? unavailable : photoInfo.whiteBalance); // -- Video information ------------------------------------------ VideoInfoContainer videoInfo = meta.getVideoInformation(); if (videoInfo.isEmpty()) { widget(2)->hide(); } else { widget(2)->show(); } d->labelVideoAspectRatio->setAdjustedText(videoInfo.aspectRatio.isEmpty() ? unavailable : videoInfo.aspectRatio); d->labelVideoAudioBitRate->setAdjustedText(videoInfo.audioBitRate.isEmpty() ? unavailable : videoInfo.audioBitRate); d->labelVideoAudioChannelType->setAdjustedText(videoInfo.audioChannelType.isEmpty() ? unavailable : videoInfo.audioChannelType); d->labelVideoAudioCompressor->setAdjustedText(videoInfo.audioCompressor.isEmpty() ? unavailable : videoInfo.audioCompressor); d->labelVideoDuration->setAdjustedText(videoInfo.duration.isEmpty() ? unavailable : videoInfo.duration); d->labelVideoFrameRate->setAdjustedText(videoInfo.frameRate.isEmpty() ? unavailable : videoInfo.frameRate); d->labelVideoVideoCodec->setAdjustedText(videoInfo.videoCodec.isEmpty() ? unavailable : videoInfo.videoCodec); }
void IPTCStatus::applyMetadata(QByteArray& iptcData) { DMetadata meta; meta.setIptc(iptcData); if (d->objectNameCheck->isChecked()) meta.setIptcTagString("Iptc.Application2.ObjectName", d->objectNameEdit->text()); else meta.removeIptcTag("Iptc.Application2.ObjectName"); if (d->statusCheck->isChecked()) meta.setIptcTagString("Iptc.Application2.EditStatus", d->statusEdit->text()); else meta.removeIptcTag("Iptc.Application2.EditStatus"); if (d->JobIDCheck->isChecked()) meta.setIptcTagString("Iptc.Application2.FixtureId", d->JobIDEdit->text()); else meta.removeIptcTag("Iptc.Application2.FixtureId"); if (d->specialInstructionCheck->isChecked()) meta.setIptcTagString("Iptc.Application2.SpecialInstructions", d->specialInstructionEdit->toPlainText()); else meta.removeIptcTag("Iptc.Application2.SpecialInstructions"); iptcData = meta.getIptc(); }