File indexing completed on 2024-04-21 15:22:27
0001 /* 0002 A command line tool to set faces in Picassa format 0003 0004 SPDX-FileCopyrightText: 2013 Munteanu Veaceslav <slavuttici at gmail dot com> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 // Qt includes 0010 0011 #include <QString> 0012 #include <QFile> 0013 #include <QDebug> 0014 0015 // Local includes 0016 0017 #include "kexiv2.h" 0018 0019 using namespace KExiv2Iface; 0020 0021 bool setFaceTags(KExiv2& meta,const char* xmpTagName,const QMap<QString,QRectF>& faces, 0022 bool setProgramName) 0023 { 0024 0025 Q_UNUSED(setProgramName); 0026 meta.setXmpTagString(xmpTagName,QString(),KExiv2::XmpTagType(1),false); 0027 0028 QString qxmpTagName(QString::fromLatin1(xmpTagName)); 0029 QString nameTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Name"); 0030 QString typeTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Type"); 0031 QString areaTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area"); 0032 QString areaxTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:x"); 0033 QString areayTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:y"); 0034 QString areawTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:w"); 0035 QString areahTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:h"); 0036 QString areanormTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:unit"); 0037 0038 QMap<QString,QRectF>::const_iterator it = faces.constBegin(); 0039 int i =1; 0040 while(it != faces.constEnd()) 0041 { 0042 qreal x,y,w,h; 0043 it.value().getRect(&x,&y,&w,&h); 0044 /** Set tag name **/ 0045 meta.setXmpTagString(nameTagKey.arg(i).toLatin1().constData(),it.key(), 0046 KExiv2::XmpTagType(0),false); 0047 /** Set tag type as Face **/ 0048 meta.setXmpTagString(typeTagKey.arg(i).toLatin1().constData(),QString::fromLatin1("Face"), 0049 KExiv2::XmpTagType(0),false); 0050 /** Set tag Area, with xmp type struct **/ 0051 meta.setXmpTagString(areaTagKey.arg(i).toLatin1().constData(),QString(), 0052 KExiv2::XmpTagType(2),false); 0053 /** Set stArea:x inside Area structure **/ 0054 meta.setXmpTagString(areaxTagKey.arg(i).toLatin1().constData(),QString::number(x), 0055 KExiv2::XmpTagType(0),false); 0056 /** Set stArea:y inside Area structure **/ 0057 meta.setXmpTagString(areayTagKey.arg(i).toLatin1().constData(),QString::number(y), 0058 KExiv2::XmpTagType(0),false); 0059 /** Set stArea:w inside Area structure **/ 0060 meta.setXmpTagString(areawTagKey.arg(i).toLatin1().constData(),QString::number(w), 0061 KExiv2::XmpTagType(0),false); 0062 /** Set stArea:h inside Area structure **/ 0063 meta.setXmpTagString(areahTagKey.arg(i).toLatin1().constData(),QString::number(h), 0064 KExiv2::XmpTagType(0),false); 0065 /** Set stArea:unit inside Area structure as normalized **/ 0066 meta.setXmpTagString(areanormTagKey.arg(i).toLatin1().constData(),QString::fromLatin1("normalized"), 0067 KExiv2::XmpTagType(0),false); 0068 0069 ++it; 0070 ++i; 0071 } 0072 0073 return true; 0074 0075 } 0076 0077 void removeFaceTags(KExiv2& meta,const char* xmpTagName) 0078 { 0079 QString qxmpTagName(QString::fromLatin1(xmpTagName)); 0080 QString regionTagKey = qxmpTagName + QString::fromLatin1("[%1]"); 0081 QString nameTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Name"); 0082 QString typeTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Type"); 0083 QString areaTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area"); 0084 QString areaxTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:x"); 0085 QString areayTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:y"); 0086 QString areawTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:w"); 0087 QString areahTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:h"); 0088 QString areanormTagKey = qxmpTagName + QString::fromLatin1("[%1]/mwg-rs:Area/stArea:unit"); 0089 0090 meta.removeXmpTag(xmpTagName,false); 0091 bool dirty = true; 0092 int i =1; 0093 0094 while(dirty) 0095 { 0096 dirty = false; 0097 dirty |=meta.removeXmpTag(regionTagKey.arg(i).toLatin1().constData(),false); 0098 dirty |=meta.removeXmpTag(nameTagKey.arg(i).toLatin1().constData(),false); 0099 dirty |=meta.removeXmpTag(typeTagKey.arg(i).toLatin1().constData(),false); 0100 dirty |=meta.removeXmpTag(areaTagKey.arg(i).toLatin1().constData(),false); 0101 dirty |=meta.removeXmpTag(areaxTagKey.arg(i).toLatin1().constData(),false); 0102 dirty |=meta.removeXmpTag(areayTagKey.arg(i).toLatin1().constData(),false); 0103 dirty |=meta.removeXmpTag(areawTagKey.arg(i).toLatin1().constData(),false); 0104 dirty |=meta.removeXmpTag(areahTagKey.arg(i).toLatin1().constData(),false); 0105 dirty |=meta.removeXmpTag(areanormTagKey.arg(i).toLatin1().constData(),false); 0106 i++; 0107 } 0108 } 0109 0110 int main (int argc, char **argv) 0111 { 0112 if (argc != 3) 0113 { 0114 qDebug() << "Adding a face rectangle to image"; 0115 qDebug() << "Usage: <add/remove> <image>"; 0116 return -1; 0117 } 0118 0119 QString filePath(QString::fromLatin1(argv[2])); 0120 0121 KExiv2Iface::KExiv2::initializeExiv2(); 0122 KExiv2 meta; 0123 meta.load(filePath); 0124 meta.setWriteRawFiles(true); 0125 0126 /** Add a random rectangle with facetag Bob **/ 0127 QString name = QString::fromLatin1("Bob Marley"); 0128 float x =0.5; 0129 float y =0.5; 0130 float w = 60; 0131 float h = 60; 0132 0133 QRectF rect(x,y,w,h); 0134 0135 QMap<QString, QRectF> faces; 0136 0137 faces[name] = rect; 0138 0139 QString name2 = QString::fromLatin1("Hello Kitty!"); 0140 QRectF rect2(0.4,0.4,30,30); 0141 0142 faces[name2] = rect2; 0143 0144 bool g = meta.supportXmp(); 0145 0146 qDebug() << "Image support XMP" << g; 0147 0148 const QString bag = QString::fromLatin1("Xmp.mwg-rs.Regions/mwg-rs:RegionList"); 0149 0150 QString op(QString::fromLatin1(argv[1])); 0151 0152 if (op == QString::fromLatin1("add")) 0153 setFaceTags(meta,bag.toLatin1().constData(),faces,false); 0154 else 0155 removeFaceTags(meta,bag.toLatin1().constData()); 0156 0157 meta.applyChanges(); 0158 0159 QString recoverName = QString::fromLatin1("Xmp.mwg-rs.Regions/mwg-rs:RegionList[1]/mwg-rs:Name"); 0160 0161 KExiv2 meta2; 0162 meta2.load(filePath); 0163 meta2.setWriteRawFiles(true); 0164 0165 QString nameR = meta2.getXmpTagString(recoverName.toLatin1().constData(),false); 0166 0167 qDebug() << "Saved name is:" << nameR; 0168 0169 KExiv2Iface::KExiv2::cleanupExiv2(); 0170 return 0; 0171 }