Пример #1
0
void ExifTransfer::copyIPTC() {
    const Exiv2::IptcData & srcIptc = src->iptcData();
    Exiv2::IptcData & dstIptc = dst->iptcData();
    for (const auto & datum : srcIptc) {
        if (dstIptc.findKey(Exiv2::IptcKey(datum.key())) == dstIptc.end()) {
            dstIptc.add(datum);
        }
    }
}
Пример #2
0
int main(int argc, char* const argv[])
try {
    
    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << " file\n";
        return 1;
    }
    
    const char* path=argv[1];
        
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path);
    assert(image.get() != 0);
    image->readMetadata();
        
    Jzon::Object root;

    const char*    FS="FS";
    Jzon::Object      fs  ;
    root.Add      (FS,fs) ;
    fileSystemPush(path,root.Get(FS));
    
	Exiv2::ExifData &exifData = image->exifData();
    for ( ExifData::const_iterator i = exifData.begin(); i != exifData.end() ; ++i ) {
        std::string   key ;
        push(objectForKey(i->key(),key,root),key,i);
    }

	Exiv2::IptcData &iptcData = image->iptcData();
    for (Exiv2::IptcData::const_iterator i = iptcData.begin(); i != iptcData.end(); ++i) {
        std::string key ;
        push(objectForKey(i->key(),key,root),key,i);
    }

	Exiv2::XmpData  &xmpData  = image->xmpData();
    for (Exiv2::XmpData::const_iterator i = xmpData.begin(); i != xmpData.end(); ++i) {
        std::string key ;
        push(objectForKey(i->key(),key,root),key,i);
    }
/*
    This is only for testing long paths    
    {
    	ExifData::const_iterator i = exifData.begin();
    	std::string key;
    	push(objectForKey("This.Is.A.Rather.Long.Path.Key",key,root),key,i);
    }
*/        
    Jzon::Writer writer(root,Jzon::StandardFormat);
    writer.Write();
    std::cout << writer.GetResult() << std::endl;
    return 0;
}
        
//catch (std::exception& e) {
//catch (Exiv2::AnyError& e) {
catch (Exiv2::Error& e) {
    std::cout << "Caught Exiv2 exception '" << e.what() << "'\n";
    return -1;
}
Пример #3
0
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
{
try {
    // Handle command line arguments
    Params params;
    if (params.getopt(argc, argv)) {
        params.usage();
        return 1;
    }
    if (params.help_) {
        params.help();
        return 2;
    }

    // Use MemIo to increase test coverage.
    Exiv2::BasicIo::AutoPtr fileIo(new Exiv2::FileIo(params.read_));
    Exiv2::BasicIo::AutoPtr memIo(new Exiv2::MemIo);
    memIo->transfer(*fileIo);

    Exiv2::Image::AutoPtr readImg = Exiv2::ImageFactory::open(memIo);
    assert(readImg.get() != 0);
    readImg->readMetadata();

    Exiv2::Image::AutoPtr writeImg = Exiv2::ImageFactory::open(params.write_);
    assert(writeImg.get() != 0);
    if (params.preserve_) writeImg->readMetadata();
    if (params.iptc_) {
        writeImg->setIptcData(readImg->iptcData());
    }
    if (params.exif_) {
        writeImg->setExifData(readImg->exifData());
    }
    if (params.comment_) {
        writeImg->setComment(readImg->comment());
    }
    if (params.xmp_) {
        writeImg->setXmpData(readImg->xmpData());
    }

    try {
        writeImg->writeMetadata();
    }
    catch (const Exiv2::AnyError&) {
        std::cerr << params.progname() <<
            ": Could not write metadata to (" << params.write_ << ")\n";
        return 8;
    }

    return 0;
}
catch (Exiv2::AnyError& e) {
    std::cerr << "Caught Exiv2 exception '" << e << "'\n";
    return 10;
}
}
Пример #4
0
bool KExiv2::loadFromData(const QByteArray& imgData) const
{
    if (imgData.isEmpty())
        return false;

    try
    {
        Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open((Exiv2::byte*)imgData.data(), imgData.size());

        d->filePath.clear();
        image->readMetadata();

        // Size and mimetype ---------------------------------

        d->pixelSize = QSize(image->pixelWidth(), image->pixelHeight());
        d->mimeType  = QString::fromLatin1(image->mimeType().c_str());

        // Image comments ---------------------------------

        d->imageComments() = image->comment();

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

        d->exifMetadata() = image->exifData();

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

        d->iptcMetadata() = image->iptcData();

#ifdef _XMP_SUPPORT_

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

        d->xmpMetadata() = image->xmpData();

#endif // _XMP_SUPPORT_

        return true;
    }
    catch( Exiv2::Error& e )
    {
        d->printExiv2ExceptionError(QString::fromLatin1("Cannot load metadata using Exiv2 "), e);
    }
    catch(...)
    {
        qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
    }

    return false;
}
Пример #5
0
void ThumbView::updateExifInfo(QString imageFullPath)
{
	Exiv2::Image::AutoPtr exifImage;
	QString key;
	QString val;

	try	{
		exifImage = Exiv2::ImageFactory::open(imageFullPath.toStdString());
		exifImage->readMetadata();
	}
	catch (Exiv2::Error &error) {
		return;
	}

	Exiv2::ExifData &exifData = exifImage->exifData();
	if (!exifData.empty()) {
		Exiv2::ExifData::const_iterator end = exifData.end();
		infoView->addTitleEntry("Exif");
		for (Exiv2::ExifData::const_iterator md = exifData.begin(); md != end; ++md) {
			key = QString::fromUtf8(md->tagName().c_str());
			val = QString::fromUtf8(md->print().c_str());
			infoView->addEntry(key, val);
		}
	}

	Exiv2::IptcData &iptcData = exifImage->iptcData();
	if (!iptcData.empty()) {
		Exiv2::IptcData::iterator end = iptcData.end();
		infoView->addTitleEntry("IPTC");
		for (Exiv2::IptcData::iterator md = iptcData.begin(); md != end; ++md) {
			key = QString::fromUtf8(md->tagName().c_str());
			val = QString::fromUtf8(md->print().c_str());
	   		infoView->addEntry(key, val);
		}
	}

	Exiv2::XmpData &xmpData = exifImage->xmpData();
	if (!xmpData.empty()) {
		Exiv2::XmpData::iterator end = xmpData.end();
		infoView->addTitleEntry("XMP");
		for (Exiv2::XmpData::iterator md = xmpData.begin(); md != end; ++md) {
			key = QString::fromUtf8(md->tagName().c_str());
			val = QString::fromUtf8(md->print().c_str());
			infoView->addEntry(key, val);
		}
	}
}
Пример #6
0
void ExifTools::copyExif(const QString &sourceStr, const QString &destStr)
{
        Exiv2::Image::AutoPtr sourceImageData =
                Exiv2::ImageFactory::open(QFile::encodeName(sourceStr).data());
        sourceImageData->readMetadata();

        Exiv2::ExifData exifData = sourceImageData->exifData();
        Exiv2::IptcData iptcData = sourceImageData->iptcData();

        Exiv2::ExifThumb exifThumb(exifData);
        exifThumb.erase();

        Exiv2::Image::AutoPtr destImageData =
                Exiv2::ImageFactory::open(QFile::encodeName(destStr).data());
        destImageData->setExifData(exifData);
        destImageData->setIptcData(iptcData);
        destImageData->writeMetadata();
}
Пример #7
0
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;
}
Пример #8
0
    bool Exiv2ReadingWorker::readMetadata(Models::ArtworkMetadata *artwork, ImportDataResult &importResult) {
        const QString &filepath = artwork->getFilepath();

#if defined(Q_OS_WIN)
        Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(filepath.toStdWString());
#else
        Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(filepath.toStdString());
#endif
        Q_ASSERT(image.get() != NULL);
        image->readMetadata();

        Exiv2::XmpData &xmpData = image->xmpData();
        Exiv2::ExifData &exifData = image->exifData();
        Exiv2::IptcData &iptcData = image->iptcData();

        QString iptcEncoding = getIptcCharset(iptcData).toUpper();
        bool isIptcUtf8 = (iptcEncoding == QLatin1String("UTF-8")) || (iptcEncoding == QLatin1String("UTF8"));

        importResult.FilePath = filepath;
        importResult.Description = retrieveDescription(xmpData, exifData, iptcData, isIptcUtf8);
        importResult.Title = retrieveTitle(xmpData, exifData, iptcData, isIptcUtf8);
        importResult.Keywords = retrieveKeywords(xmpData, exifData, iptcData, isIptcUtf8);
        importResult.DateTimeOriginal = retrieveDateTime(xmpData, exifData, iptcData, isIptcUtf8);

        MetadataSavingCopy copy;
        if (copy.readFromFile(filepath)) {
            importResult.BackupDict = copy.getInfo();
        }

        QFileInfo fi(filepath);
        importResult.FileSize = fi.size();

        Models::ImageArtwork *imageArtwork = dynamic_cast<Models::ImageArtwork*>(artwork);
        if (imageArtwork != NULL) {
            QImageReader reader(filepath);
            importResult.ImageSize = reader.size();
        }

        return true;
    }
Пример #9
0
int main(int argc, char* const argv[])
try {

    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << " file\n";
        return 1;
    }

    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]);
    assert (image.get() != 0);
    image->readMetadata();

    Exiv2::IptcData &iptcData = image->iptcData();
    if (iptcData.empty()) {
        std::string error(argv[1]);
        error += ": No IPTC data found in the file";
        throw Exiv2::Error(1, error);
    }

    Exiv2::IptcData::iterator end = iptcData.end();
    for (Exiv2::IptcData::iterator md = iptcData.begin(); md != end; ++md) {
        std::cout << std::setw(44) << std::setfill(' ') << std::left
                  << md->key() << " "
                  << "0x" << std::setw(4) << std::setfill('0') << std::right
                  << std::hex << md->tag() << " "
                  << std::setw(9) << std::setfill(' ') << std::left
                  << md->typeName() << " "
                  << std::dec << std::setw(3)
                  << std::setfill(' ') << std::right
                  << md->count() << "  "
                  << std::dec << md->value()
                  << std::endl;
    }

    return 0;
}
catch (Exiv2::AnyError& e) {
    std::cout << "Caught Exiv2 exception '" << e << "'\n";
    return -1;
}
Пример #10
0
int main(int argc, char* const argv[])
try {
    if (argc != 3) {
        std::cout << "Usage: " << argv[0] << " image datafile\n";
        return 1;
    }
    std::string file(argv[1]);
    std::string data(argv[2]);

    // Read data file into data buffer
    Exiv2::FileIo io(data);
    if (io.open() != 0) {
      throw Exiv2::Error(Exiv2::kerDataSourceOpenFailed, io.path(), Exiv2::strError());
    }
    Exiv2::DataBuf buf((long)io.size());
    std::cout << "Reading " << buf.size_ << " bytes from " << data << "\n";
    io.read(buf.pData_, buf.size_);
    if (io.error() || !io.eof()) throw Exiv2::Error(Exiv2::kerFailedToReadImageData);

    // Read metadata from file
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(file);
    assert(image.get() != 0);
    image->readMetadata();

    // Set Preview field to the content of the data file
    Exiv2::DataValue value;
    value.read(buf.pData_, buf.size_);
    Exiv2::IptcData& iptcData = image->iptcData();
    std::cout << "IPTC fields: " << iptcData.size() << "\n";
    iptcData["Iptc.Application2.Preview"] = value;
    std::cout << "IPTC fields: " << iptcData.size() << "\n";

    // Set IRB, compare with IPTC raw data
    Exiv2::DataBuf irb = Exiv2::Photoshop::setIptcIrb(0, 0, iptcData);
    std::cout << "IRB buffer : " << irb.size_ << "\n";
    const Exiv2::byte* record;
    uint32_t sizeHdr;
    uint32_t sizeData;
    Exiv2::Photoshop::locateIptcIrb(irb.pData_, irb.size_, &record, &sizeHdr, &sizeData);
    Exiv2::DataBuf rawIptc = Exiv2::IptcParser::encode(iptcData);
    std::cout << "Comparing IPTC and IRB size... ";
    if (static_cast<uint32_t>(rawIptc.size_) != sizeData) {
        std::cout << "not ";
    }
    std::cout << "ok\n";

    std::cout << "Comparing IPTC and IRB data... ";
    if (0 != memcmp(rawIptc.pData_, record + sizeHdr, sizeData)) {
        std::cout << "not ";
    }
    std::cout << "ok\n";

    // Set Iptc data and write it to the file
    image->writeMetadata();

    return 0;
}
catch (Exiv2::AnyError& e) {
    std::cout << "Caught Exiv2 exception '" << e << "'\n";
    return -1;
}
Пример #11
0
bool KExiv2::load(const QString& filePath) const
{
    if (filePath.isEmpty())
    {
        return false;
    }

    d->filePath      = filePath;
    bool hasLoaded   = false;

    try
    {
        Exiv2::Image::AutoPtr image;

        image        = Exiv2::ImageFactory::open((const char*)(QFile::encodeName(filePath)).constData());

        image->readMetadata();

        // Size and mimetype ---------------------------------

        d->pixelSize = QSize(image->pixelWidth(), image->pixelHeight());
        d->mimeType  = QString::fromLatin1(image->mimeType().c_str());

        // Image comments ---------------------------------

        d->imageComments() = image->comment();

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

        d->exifMetadata() = image->exifData();

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

        d->iptcMetadata() = image->iptcData();

#ifdef _XMP_SUPPORT_

        // Xmp metadata -----------------------------------
        d->xmpMetadata() = image->xmpData();

#endif // _XMP_SUPPORT_

        hasLoaded = true;
    }
    catch( Exiv2::Error& e )
    {
        d->printExiv2ExceptionError(QString::fromLatin1("Cannot load metadata from file "), e);
    }
    catch(...)
    {
        qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
    }

#ifdef _XMP_SUPPORT_
    try
    {
        if (d->useXMPSidecar4Reading)
        {
            QString xmpSidecarPath = sidecarFilePathForFile(filePath);
            QFileInfo xmpSidecarFileInfo(xmpSidecarPath);

            Exiv2::Image::AutoPtr xmpsidecar;

            if (xmpSidecarFileInfo.exists() && xmpSidecarFileInfo.isReadable())
            {
                // Read sidecar data
                xmpsidecar = Exiv2::ImageFactory::open(QFile::encodeName(xmpSidecarPath).constData());
                xmpsidecar->readMetadata();

                // Merge
                d->loadSidecarData(xmpsidecar);
                hasLoaded = true;
            }
        }
    }
    catch( Exiv2::Error& e )
    {
        d->printExiv2ExceptionError(QString::fromLatin1("Cannot load XMP sidecar"), e);
    }
    catch(...)
    {
        qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
    }

#endif // _XMP_SUPPORT_

    return hasLoaded;
}
Пример #12
0
SlideShowWindow::SlideShowWindow(QWidget *parent)
	: QWidget(parent)
	, m_group(0)
	, m_scene(0)
	, m_oldScene(0)
	, m_useGLWidget(true)
	, m_glWidget(0)
	, m_graphicsView(0)
	, m_xfadeSpeed(300)
{
	QVBoxLayout *layout = new QVBoxLayout(this);
	layout->setContentsMargins(0,0,0,0);
	
	bool verbose = true;
	QString configFile = "player.ini";
	
	if(verbose)
		qDebug() << "SlideShowWindow: Reading settings from "<<configFile;
		
	QSettings settings(configFile,QSettings::IniFormat);
	
	QString str;
	QStringList parts;
	QPoint point;
	
	QString activeGroup = settings.value("config").toString();
	
	str = settings.value("verbose").toString();
	if(!str.isEmpty())
		verbose = str == "true";
	
	if(verbose && !activeGroup.isEmpty())
		qDebug() << "SlideShowWindow: Using config:"<<activeGroup;
	
	#define READ_STRING(key,default) \
		(!activeGroup.isEmpty() ? \
			(!(str = settings.value(QString("%1/%2").arg(activeGroup).arg(key)).toString()).isEmpty() ?  str : \
				settings.value(key,default).toString()) : \
			settings.value(key,default).toString())
			
	#define READ_POINT(key,default) \
		str = READ_STRING(key,default); \
		parts = str.split("x"); \
		point = QPoint(parts[0].toInt(),parts[1].toInt()); \
		if(verbose) qDebug() << "SlideShowWindow: " key ": " << point; 
		
	m_useGLWidget = READ_STRING("compat","false") == "false";
	if(m_useGLWidget)
	{
		m_glWidget = new GLWidget(this);
		layout->addWidget(m_glWidget);
		qDebug() << "SlideShowWindow: Using OpenGL to provide high-quality graphics.";
		
		m_glWidget->setCursor(Qt::BlankCursor);
	}
	else
	{
		m_graphicsView = new ScaledGraphicsView();
		m_graphicsScene = new QGraphicsScene();
		m_graphicsView->setScene(m_graphicsScene);
		m_graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
		m_graphicsScene->setSceneRect(QRectF(0,0,1000.,750.));
		m_graphicsView->setBackgroundBrush(Qt::black);
		layout->addWidget(m_graphicsView);
		
		qDebug() << "SlideShowWindow: Using vendor-provided stock graphics engine for compatibility with older hardware.";
		
		m_graphicsView->setCursor(Qt::BlankCursor);
	}
	
	
	// Window position and size
	READ_POINT("window-pos","10x10");
	QPoint windowPos = point;
	
	READ_POINT("window-size","640x480");
	QPoint windowSize = point;
	//windowSize = QPoint(3120,1050);
	
	if(verbose)
		qDebug() << "SlideShowWindow: pos:"<<windowPos<<", size:"<<windowSize;
	
	resize(windowSize.x(),windowSize.y());
	move(windowPos.x(),windowPos.y());
	
	bool frameless = READ_STRING("frameless","true") == "true";
	if(frameless)
		setWindowFlags(Qt::FramelessWindowHint);// | Qt::ToolTip);
	
	if(m_useGLWidget)
	{
		
		// Keystoning / Corner Translations
		READ_POINT("key-tl","0x0");
		m_glWidget->setTopLeftTranslation(point);
		
		READ_POINT("key-tr","0x0");
		m_glWidget->setTopRightTranslation(point);
		
		READ_POINT("key-bl","0x0");
		m_glWidget->setBottomLeftTranslation(point);
		
		READ_POINT("key-br","0x0");
		m_glWidget->setBottomRightTranslation(point);
		
		// Brightness/Contrast, Hue/Sat
		m_glWidget->setBrightness(READ_STRING("brightness","0").toInt());
		m_glWidget->setContrast(READ_STRING("contrast","0").toInt());
		m_glWidget->setHue(READ_STRING("hue","0").toInt());
		m_glWidget->setSaturation(READ_STRING("saturation","0").toInt());
		
		// Flip H/V
		bool fliph = READ_STRING("flip-h","false") == "true";
		if(verbose)
			qDebug() << "SlideShowWindow: flip-h: "<<fliph;
		m_glWidget->setFlipHorizontal(fliph);
		
		bool flipv = READ_STRING("flip-v","false") == "true";
		if(verbose)
			qDebug() << "SlideShowWindow: flip-v: "<<flipv;
		m_glWidget->setFlipVertical(flipv);
		
		// Rotate
		int rv = READ_STRING("rotate","0").toInt();
		if(verbose)
			qDebug() << "SlideShowWindow: rotate: "<<rv;
		
		if(rv != 0)
			m_glWidget->setCornerRotation(rv == -1 ? GLRotateLeft  : 
						      rv ==  1 ? GLRotateRight : 
							         GLRotateNone);
		
		// Aspet Ratio Mode
		m_glWidget->setAspectRatioMode(READ_STRING("ignore-ar","false") == "true" ? Qt::IgnoreAspectRatio : Qt::KeepAspectRatio);
		
		// Alpha Mask
		QString alphaFile = READ_STRING("alphamask","");
		if(!alphaFile.isEmpty())
		{
			QImage alphamask(alphaFile);
			if(alphamask.isNull())
				qDebug() << "SlideShowWindow: Error loading alphamask "<<alphaFile;
			else
				m_glWidget->setAlphaMask(alphamask);
		}
		
// 		GLWidgetSubview *sub1 = m_glWidget->defaultSubview();
// 		sub1->setRight(1680./3120.);
// 		
// 		GLWidgetSubview *sub2 = new GLWidgetSubview();
// 		sub2->setLeft(sub1->right());
// 		sub2->setBrightness(75);
// 		sub2->setFlipVertical(true);
// 		sub2->setFlipHorizontal(true);
// 		
// 		m_glWidget->addSubview(sub2);
	}
	
	// Canvas Size
	READ_POINT("canvas-size","1000x750");
	QSizeF canvasSize((qreal)point.x(),(qreal)point.y());
	//canvasSize = QSizeF(2000,750);
	canvasSize = QSizeF(3120,1050);
	if(m_useGLWidget)
	{
		m_glWidget->setCanvasSize(canvasSize);
	}
	else
	{
		m_graphicsScene->setSceneRect(QRectF(QPointF(0,0),canvasSize));
	}
	
	m_xfadeSpeed = READ_STRING("xfade-speed",300).toInt();
	//qDebug() << "SlideShowWindow: Crossfade speed: "<<m_xfadeSpeed;
	
// 	QString loadGroup = READ_STRING("load-group","");
// 	if(!loadGroup.isEmpty())
// 	{
// 		QFile file(loadGroup);
// 		if (!file.open(QIODevice::ReadOnly)) 
// 		{
// 			qDebug() << "SlideShowWindow: Unable to read group file: "<<loadGroup;
// 		}
// 		else
// 		{
// 			QByteArray array = file.readAll();
// 			
// 			GLSceneGroup *group = new GLSceneGroup();
// 			group->fromByteArray(array);
// 			setGroup(group);
// 			
// 			GLScene *scene = group->at(0);
// 			if(scene)
// 			{
// 				//scene->setGLWidget(this);
// 				setScene(scene);
// 				qDebug() << "SlideShowWindow: [DEBUG]: Loaded File: "<<loadGroup<<", GroupID: "<<group->groupId()<<", SceneID: "<< scene->sceneId();
// 				
// 				if(m_outputEncoder && 
// 				  !m_outputEncoder->encodingStarted())
// 					m_outputEncoder->startEncoder();
// 
// 			}
// 			else
// 			{
// 				qDebug() << "SlideShowWindow: [DEBUG]: Loaded File: "<<loadGroup<<", GroupID: "<<group->groupId()<<" - no scenes found at index 0";
// 			}
// 		}	
// 	}
// 	else
// 	{
// 		QString loadGroup = READ_STRING("collection","");
// 		if(!loadGroup.isEmpty())
// 		{
// 			QFile file(loadGroup);
// 			if (!file.open(QIODevice::ReadOnly)) 
// 			{
// 				qDebug() << "SlideShowWindow: Unable to read group file: "<<loadGroup;
// 			}
// 			else
// 			{
// 				QByteArray array = file.readAll();
// 				
// 				GLSceneGroupCollection *collection = new GLSceneGroupCollection();
// 				collection->fromByteArray(array);
// 				setGroup(collection->at(0));
// 				
// 				if(m_group)
// 				{
// 					GLScene *scene = m_group->at(0);
// 					if(scene)
// 					{
// 						//scene->setGLWidget(this);
// 						setScene(scene);
// 						qDebug() << "SlideShowWindow: [DEBUG]: Loaded File: "<<loadGroup<<", GroupID: "<<m_group->groupId()<<", SceneID: "<< scene->sceneId();
// 						
// 						GLDrawableList list = scene->drawableList();
// 						foreach(GLDrawable *gld, list)
// 							if(gld->playlist()->size() > 0)
// 								gld->playlist()->play();	
// 						
// 						if(m_outputEncoder && 
// 						!m_outputEncoder->encodingStarted())
// 							m_outputEncoder->startEncoder();
// 		
// 					}
// 					else
// 					{
// 						qDebug() << "SlideShowWindow: [DEBUG]: Loaded File: "<<loadGroup<<", GroupID: "<<m_group->groupId()<<" - no scenes found at index 0";
// 					}
// 				}
// 			}	
// 		}
// 	}


	QStringList argList = qApp->arguments();
	if(argList.size() > 1)
	{
		QString dirName = argList.at(1);
		QDir dir(dirName);
		dir.setNameFilters(QStringList() << "*.jpg" << "*.JPG" << "*.jpeg" << "*.png" << "*.PNG");
		QFileInfoList list = dir.entryInfoList(QDir::Files, QDir::Name);
		
		if(m_glWidget)
			m_glWidget->setFboEnabled(false);
		
		int spinSize = 28;
			
			
		//QStringList list = dir.entryList();
		//foreach(QString file, list)
		foreach(QFileInfo info, list)
		{
			//QFileInfo info(QString("%1/%2").arg(dirName,file));
			//if(!info.isFile())
			//	continue;
			//QString ext = info.suffix().toLower();
			//if(ext != "jpg" || ext != "png" || ext != "jpeg")
			//	continue;
			
			bool flipText = true;
			
			QString fullFile = info.absoluteFilePath();
			qDebug() << "SlideShowWindow: Loading "<<fullFile;//<<" (ext:"<<ext<<")";
			GLScene *scene = new GLScene();
			{
				QString comment = "";
				QString datetime = "";
				try
				{
					Exiv2::Image::AutoPtr exiv = Exiv2::ImageFactory::open(fullFile.toStdString()); 
					if(exiv.get() != 0)
					{
						exiv->readMetadata();
						Exiv2::ExifData& exifData = exiv->exifData();
						if (exifData.empty()) 
						{
							qDebug() << fullFile << ": No Exif data found in the file";
						}
		
						comment = exifData["Exif.Image.ImageDescription"].toString().c_str();
						comment = GLTextDrawable::htmlToPlainText(comment);
						
						datetime = exifData["Exif.Photo.DateTimeOriginal"].toString().c_str();
			
						if(comment.trimmed().isEmpty())
						{
							Exiv2::IptcData& iptcData = exiv->iptcData();
							comment = iptcData["Iptc.Application2.Caption"].toString().c_str();
							comment = GLTextDrawable::htmlToPlainText(comment);
							
							if (exifData.empty()) 
							{
								qDebug() << fullFile << ": No IPTC data found in the file";
							}
							else
							{
								qDebug() << "SlideShowWindow: IPTC Caption:"<<comment;
							}
						}
						else
						{
							qDebug() << "SlideShowWindow: EXIF Caption:"<<comment;
						}
						
						
					}
				}
				catch (Exiv2::AnyError& e) 
				{
					std::cout << "Caught Exiv2 exception '" << e << "'\n";
					//return -1;
				}
				
				GLImageDrawable *image = new GLImageDrawable(fullFile);
				
				if(canvasSize.width() > 1000)
				{
					image->setRect(QRectF(QPointF(0,0),QSize(1680,canvasSize.height())));
				}
				else
				{
					image->setRect(QRectF(QPointF(0,0),canvasSize));
				}
				//image->setCrossFadeMode(GLVideoDrawable::JustFront);
				scene->addDrawable(image);
				
				if(!comment.isEmpty())
				{
					comment = comment.replace(QRegExp("^\\s*\"([^\"]+)\"\\s*-\\s*"), "<center>\"\\1\"</center><br>");
					 
					GLTextDrawable *text = new GLTextDrawable();
					QString ptSize = "36";
					QString html = 
						"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd\">"
						"<html><head><meta name=\"qrichtext\" content=\"1\"/>"
						"<style type=\"text/css\">p, li { white-space: pre-wrap; }</style>"
						"</head>"
						"<body style=\"font-family:'Sans Serif'; font-size:" + ptSize +"pt; font-weight:600; font-style:normal;\">"
						"<table style=\"-qt-table-type: root; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;\">"
						"<tr><td style=\"border: none;\">"
						"<p style=\"margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">"
						"<span style=\"font-size:" + ptSize + "pt; font-weight:600; color:#ffffff;\">"
						+ comment +
						"</span></p></td></tr></table></body></html>";
						
					text->setText(html);
					
					//qDebug() << "File # text size:"<<size<<" @ width:"<<w<<", html:"<<html;
					if(canvasSize.width() > 1000)
					{
						QSize size = text->findNaturalSize(1400);
						
						QRectF targetRect = QRectF(0, 0, size.width(), size.height());
						targetRect.moveCenter(QRectF(1680,0,1440,900).center());
		
						text->setRect(targetRect);
						
						if(flipText)
						{
							text->setFlipVertical(true);
							text->setFlipHorizontal(true);
						}
					}
					else
					{
						int w = (int)canvasSize.width();
						QSize size = text->findNaturalSize(w);
						
						double x = (canvasSize.width() - size.width()) / 2;
						double y = canvasSize.height() - size.height() - 2;
						text->setRect(QRectF(QPointF(x,y),size));
					}
					text->setZIndex(5.);
					scene->addDrawable(text);
					
					qDebug() << "Loaded caption:"<<comment;
				}
				
				QFileInfo fileInfo(fullFile);
				QString fileName = fileInfo.baseName().toLower();
				fileName = fileName.replace(QRegExp("\\d{2,6}-\\{\\d\\}"),"");
				fileName = fileName.replace(QRegExp("(dsc_|sdc)"), "");
				
				if(!fileName.isEmpty())
				{
					GLTextDrawable *text = new GLTextDrawable();
					//QString html = QString("<span style='font-color:white;font-size:20px'>%1</font>").arg(fileName);
					
					QString ptSize = "24";
					QString html = 
						"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd\">"
						"<html><head><meta name=\"qrichtext\" content=\"1\"/>"
						"<style type=\"text/css\">p, li { white-space: pre-wrap; }</style>"
						"</head>"
						"<body style=\"font-family:'Sans Serif'; font-size:" + ptSize +"pt; font-weight:600; font-style:normal;\">"
						"<table style=\"-qt-table-type: root; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;\">"
						"<tr><td style=\"border: none;\">"
						"<p style=\"margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">"
						"<span style=\"font-size:" + ptSize + "pt; font-weight:600; color:#ffffff;\">"
						"Photograph # "+ fileName +
						"</span></p></td></tr></table></body></html>";
						
					text->setText(html);
					int w = (int)canvasSize.width();
					QSize size = text->findNaturalSize(w);
					//qDebug() << "File # text size:"<<size<<" @ width:"<<w<<", html:"<<html;
					
					if(flipText)
					{
						if(canvasSize.width() > 1000)
						{
							int spinSpace = spinSize + 10;
							
							size = text->findNaturalSize(1440);
							
							//QRectF targetRect = QRectF(0, 0, size.width(), size.height());
							//targetRect.moveCenter(QRectF(1680,0,1440,900).center());
							double x = 1680 + 10 + spinSpace;
							double y =  900 - 10 - size.height();
							QRectF rect(QPointF(x,y),size);
							//qDebug() << "Rect: "<<rect;
							text->setRect(rect);
							
							text->setFlipVertical(true);
							text->setFlipHorizontal(true);
						}
						else
						{
							// TODO flip here too
							double x = canvasSize.width() - size.width() - 2;
							double y = 2;
							text->setRect(QRectF(QPointF(x,y),size));
						}
					}
					else
					{
						double x = canvasSize.width() - size.width() - 2;
						double y = 2;
						text->setRect(QRectF(QPointF(x,y),size));
					}
					text->setZIndex(5.);
					scene->addDrawable(text);
				}
				
				if(!datetime.isEmpty())
				{
					GLTextDrawable *text = new GLTextDrawable();
					//QString html = QString("<span style='font-color:white;font-size:20px'>%1</font>").arg(fileName);
					
					// 2009:10:25 12:13:34
					QDateTime parsedDate = QDateTime::fromString(datetime, "yyyy:MM:dd hh:mm:ss");
					QString dateString = "Photographed " + parsedDate.toString("dddd, MMMM d, yyyy");
					
					QString ptSize = "24";
					QString html = 
						"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd\">"
						"<html><head><meta name=\"qrichtext\" content=\"1\"/>"
						"<style type=\"text/css\">p, li { white-space: pre-wrap; }</style>"
						"</head>"
						"<body style=\"font-family:'Sans Serif'; font-size:" + ptSize +"pt; font-weight:600; font-style:normal;\">"
						"<table style=\"-qt-table-type: root; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;\">"
						"<tr><td style=\"border: none;\">"
						"<p style=\"margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">"
						"<span style=\"font-size:" + ptSize + "pt; font-weight:600; color:#ffffff;\">"
						+ dateString +
						"</span></p></td></tr></table></body></html>";
						
					text->setText(html);
					int w = (int)canvasSize.width();
					QSize size = text->findNaturalSize(w);
					//qDebug() << "File # text size:"<<size<<" @ width:"<<w<<", html:"<<html;
					
					if(flipText)
					{
						if(canvasSize.width() > 1000)
						{
							//int spinSpace = spinSize + 10;
							
							size = text->findNaturalSize(1440);
							
							//QRectF targetRect = QRectF(0, 0, size.width(), size.height());
							//targetRect.moveCenter(QRectF(1680,0,1440,900).center());
							double x = 1680 + (1440 - size.width()) / 2;
							double y =  10; //900 - 10 - size.height();
							QRectF rect(QPointF(x,y),size);
							//qDebug() << "Rect: "<<rect;
							text->setRect(rect);
							
							text->setFlipVertical(true);
							text->setFlipHorizontal(true);
						}
						else
						{
							// TODO 
// 							double x = canvasSize.width() - size.width() - 2;
// 							double y = 2;
// 							text->setRect(QRectF(QPointF(x,y),size));
						}
					}
					else
					{
						// TODO
// 						double x = canvasSize.width() - size.width() - 2;
// 						double y = 2;
// 						text->setRect(QRectF(QPointF(x,y),size));
					}
					text->setZIndex(5.);
					scene->addDrawable(text);
				}
			}
			
			
			m_scenes << scene;
		}
Пример #13
0
void MetaEngine::Private::loadSidecarData(Exiv2::Image::AutoPtr xmpsidecar)
{
    // Having a sidecar is a special situation.
    // The sidecar data often "dominates", see in particular bug 309058 for important aspects:
    // If a field is removed from the sidecar, we must ignore (older) data for this field in the file.

    // First: Ignore file XMP, only use sidecar XMP
    xmpMetadata()     = xmpsidecar->xmpData();
    loadedFromSidecar = true;

    // EXIF
    // Four groups of properties are mapped between EXIF and XMP:
    // Date/Time, Description, Copyright, Creator
    // A few more tags are defined "writeback" tags in the XMP specification, the sidecar value therefore overrides the Exif value.
    // The rest is kept side-by-side.
    // (to understand, remember that the xmpsidecar's Exif data is actually XMP data mapped back to Exif)

    // Description, Copyright and Creator is dominated by the sidecar: Remove file Exif fields, if field not in XMP.
    ExifMergeHelper exifDominatedHelper;
    exifDominatedHelper << QLatin1String("Exif.Image.ImageDescription")
                        << QLatin1String("Exif.Photo.UserComment")
                        << QLatin1String("Exif.Image.Copyright")
                        << QLatin1String("Exif.Image.Artist");
    exifDominatedHelper.exclusiveMerge(xmpsidecar->exifData(), exifMetadata());
    // Date/Time and "the few more" from the XMP spec are handled as writeback
    // Note that Date/Time mapping is slightly contradictory in latest specs.
    ExifMergeHelper exifWritebackHelper;
    exifWritebackHelper << QLatin1String("Exif.Image.DateTime")
                        << QLatin1String("Exif.Image.DateTime")
                        << QLatin1String("Exif.Photo.DateTimeOriginal")
                        << QLatin1String("Exif.Photo.DateTimeDigitized")
                        << QLatin1String("Exif.Image.Orientation")
                        << QLatin1String("Exif.Image.XResolution")
                        << QLatin1String("Exif.Image.YResolution")
                        << QLatin1String("Exif.Image.ResolutionUnit")
                        << QLatin1String("Exif.Image.Software")
                        << QLatin1String("Exif.Photo.RelatedSoundFile");
    exifWritebackHelper.mergeFields(xmpsidecar->exifData(), exifMetadata());

    // IPTC
    // These fields cover almost all relevant IPTC data and are defined in the XMP specification for reconciliation.
    IptcMergeHelper iptcDominatedHelper;
    iptcDominatedHelper << QLatin1String("Iptc.Application2.ObjectName")
                        << QLatin1String("Iptc.Application2.Urgency")
                        << QLatin1String("Iptc.Application2.Category")
                        << QLatin1String("Iptc.Application2.SuppCategory")
                        << QLatin1String("Iptc.Application2.Keywords")
                        << QLatin1String("Iptc.Application2.SubLocation")
                        << QLatin1String("Iptc.Application2.SpecialInstructions")
                        << QLatin1String("Iptc.Application2.Byline")
                        << QLatin1String("Iptc.Application2.BylineTitle")
                        << QLatin1String("Iptc.Application2.City")
                        << QLatin1String("Iptc.Application2.ProvinceState")
                        << QLatin1String("Iptc.Application2.CountryCode")
                        << QLatin1String("Iptc.Application2.CountryName")
                        << QLatin1String("Iptc.Application2.TransmissionReference")
                        << QLatin1String("Iptc.Application2.Headline")
                        << QLatin1String("Iptc.Application2.Credit")
                        << QLatin1String("Iptc.Application2.Source")
                        << QLatin1String("Iptc.Application2.Copyright")
                        << QLatin1String("Iptc.Application2.Caption")
                        << QLatin1String("Iptc.Application2.Writer");
    iptcDominatedHelper.exclusiveMerge(xmpsidecar->iptcData(), iptcMetadata());

    IptcMergeHelper iptcWritebackHelper;
    iptcWritebackHelper << QLatin1String("Iptc.Application2.DateCreated")
                        << QLatin1String("Iptc.Application2.TimeCreated")
                        << QLatin1String("Iptc.Application2.DigitizationDate")
                        << QLatin1String("Iptc.Application2.DigitizationTime");
    iptcWritebackHelper.mergeFields(xmpsidecar->iptcData(), iptcMetadata());

    /*
     * TODO: Exiv2 (referring to 0.23) does not correctly synchronize all times values as given below.
     * Time values and their synchronization:
     * Original Date/Time – Creation date of the intellectual content (e.g. the photograph),
       rather than the creatio*n date of the content being shown
        Exif DateTimeOriginal (36867, 0x9003) and SubSecTimeOriginal (37521, 0x9291)
        IPTC DateCreated (IIM 2:55, 0x0237) and TimeCreated (IIM 2:60, 0x023C)
        XMP (photoshop:DateCreated)
     * Digitized Date/Time – Creation date of the digital representation
        Exif DateTimeDigitized (36868, 0x9004) and SubSecTimeDigitized (37522, 0x9292)
        IPTC DigitalCreationDate (IIM 2:62, 0x023E) and DigitalCreationTime (IIM 2:63, 0x023F)
        XMP (xmp:CreateDate)
     * Modification Date/Time – Modification date of the digital image file
        Exif DateTime (306, 0x132) and SubSecTime (37520, 0x9290)
        XMP (xmp:ModifyDate)
     */
}