void ImageManager::ThumbnailCache::load() { QFile file( thumbnailPath( QString::fromLatin1("thumbnailindex")) ); if ( !file.exists() ) return; file.open(QIODevice::ReadOnly); QDataStream stream(&file); int version; stream >> version; if ( version != FILEVERSION ) return; //Discard cache int count; stream >> m_currentFile >> m_currentOffset >> count; for ( int i = 0; i < count; ++i ) { QString name; int fileIndex; int offset; int size; stream >> name >> fileIndex >> offset >> size; m_map.insert( DB::FileName::fromRelativePath(name), CacheFileInfo( fileIndex, offset, size ) ); } }
QImage ThumbnailCache::loadImage(const QUrl &url) const { const QString fileName = thumbnailPath(url); QImageReader reader(fileName); reader.setQuality(25); if (reader.supportsOption(QImageIOHandler::Size)) { QSize size = reader.size(); if (!reader.supportsOption(QImageIOHandler::ScaledSize) && (size.width() > 1280 || size.height() > 1280)) { return QImage(); } if (size.width() > ThumbnailModel::thumbnailSize.width() || size.height() > ThumbnailModel::thumbnailSize.height()) { size.scale(ThumbnailModel::thumbnailSize, Qt::KeepAspectRatio); } reader.setScaledSize(size); } else { reader.setScaledSize(ThumbnailModel::thumbnailSize); } return reader.read(); }
ImageManager::ThumbnailCache::ThumbnailCache() : m_currentFile(0), m_currentOffset(0), m_unsaved(0) { m_memcache = new QCache<int,ThumbnailMapping>(LRU_SIZE); const QString dir = thumbnailPath(QString()); if ( !QFile::exists(dir) ) QDir().mkpath(dir); load(); m_timer = new QTimer(this); connect(m_timer, &QTimer::timeout, this, &ThumbnailCache::save); }
void ImageManager::ThumbnailCache::save() const { m_timer->stop(); m_unsaved = 0; QTemporaryFile file; if ( !file.open() ) { qWarning("Failed to create temporary file"); return; } QDataStream stream(&file); stream << FILEVERSION << m_currentFile << m_currentOffset << m_map.count(); for( QMap<DB::FileName,CacheFileInfo>::ConstIterator it = m_map.begin(); it != m_map.end(); ++it ) { const CacheFileInfo& cacheInfo = it.value(); stream << it.key().relative() << cacheInfo.fileIndex << cacheInfo.offset << cacheInfo.size; } file.close(); const QString realFileName = thumbnailPath(QString::fromLatin1("thumbnailindex")); QFile::remove( realFileName ); if ( !file.copy( realFileName ) ) qWarning("Failed to copy the temporary file %s to %s", qPrintable( file.fileName() ), qPrintable( realFileName ) ); QFile realFile( realFileName ); realFile.open( QIODevice::ReadOnly ); realFile.setPermissions( QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::WriteGroup | QFile::ReadOther ); realFile.close(); }
QString ThumbnailModel::imagePath(const QModelIndex &index) const { QUrl url = itemUrl(index); return url.isValid() ? thumbnailPath(url) : QString(); }
void SimpleViewer::processQUrlList(QList<QUrl>& images, QDomDocument& xmlDoc, QDomElement& galleryElem, QDomElement& photosElem) { QImage image; QImage thumbnail; QString tmp; QString newName; int index = 1; int maxSize = d->settings->imagesExportSize; bool resizeImages = d->settings->resizeExportImages; bool fixOrientation = d->settings->fixOrientation; QUrl thumbsDir = QUrl::fromLocalFile(d->tempDir->path()); thumbsDir.setPath(thumbsDir.path() + QLatin1String("/thumbs/")); QUrl imagesDir = QUrl::fromLocalFile(d->tempDir->path()); imagesDir.setPath(imagesDir.path() + QLatin1String("/images/")); qSort(images.begin(), images.end(), cmpUrl); for (QList<QUrl>::ConstIterator it = images.constBegin(); !d->canceled && (it != images.constEnd()) ; ++it) { QApplication::processEvents(); QUrl url = *it; QFileInfo fi(url.toLocalFile()); //video can't be exported, need to add for all video files if (fi.suffix().toUpper() == QLatin1String("MOV")) continue; d->progressWdg->addedAction(i18n("Processing %1", url.fileName()), StartingMessage); // Clear image. image = QImage(); if (d->interface) { image = d->interface->preview(url); } if (image.isNull()) { image.load(url.toLocalFile()); } if (image.isNull()) { d->progressWdg->addedAction(i18n("Could not open image '%1'", url.fileName()), WarningMessage); continue; } if (d->settings->plugType == 0) { // Thumbnails are generated only for simpleviewer plugin if (!createThumbnail(image, thumbnail)) { d->progressWdg->addedAction(i18n("Could not create thumbnail from '%1'", url.fileName()), WarningMessage); continue; } } if (resizeImages && !resizeImage(image, maxSize, image)) { d->progressWdg->addedAction(i18n("Could not resize image '%1'", url.fileName()), WarningMessage); continue; } if (d->meta && d->meta->load(url)) { bool rotated = false; newName = QString::fromUtf8("%1.%2").arg(tmp.sprintf("%03i", index)).arg(QLatin1String("jpg")); if (d->settings->plugType == 0) { QUrl thumbnailPath(thumbsDir); thumbnailPath.setPath(thumbnailPath.path() + newName); if (resizeImages && fixOrientation) d->meta->rotateExifQImage(thumbnail, d->meta->getImageOrientation()); thumbnail.save(thumbnailPath.toLocalFile(), "JPEG"); } QUrl imagePath(imagesDir); imagePath.setPath(imagePath.path() + newName); if (resizeImages && fixOrientation) rotated = d->meta->rotateExifQImage(image, d->meta->getImageOrientation()); image.save(imagePath.toLocalFile(), "JPEG"); // Backup metadata from original image. d->meta->setImageProgramId(QLatin1String("Kipi-plugins"), kipipluginsVersion()); d->meta->setImageDimensions(image.size()); if (rotated) d->meta->setImageOrientation(MetadataProcessor::NORMAL); d->meta->save(imagePath); } d->width = image.width(); d->height = image.height(); if (d->settings->plugType!=2) cfgAddImage(xmlDoc, galleryElem, url, newName); else cfgAddImage(xmlDoc, photosElem, url, newName); d->progressWdg->setProgress(++d->action, d->totalActions); index++; } }
QString ImageManager::ThumbnailCache::fileNameForIndex( int index ) const { return thumbnailPath(QString::fromLatin1("thumb-") + QString::number(index) ); }
/*! Loads a thumbnail representation of \a content. The thumbnail will be scaled to \a size according to the given aspect ratio mode. */ QImage QContentStore::thumbnail(const QContent &content, const QSize &size, Qt::AspectRatioMode mode) { QImage thumbnail; QString thumbPath = thumbnailPath(content.fileName()); QFileInfo thumbInfo(thumbPath); if (thumbInfo.exists()) { if (thumbInfo.lastModified() > content.lastUpdated()) thumbnail = readThumbnail(thumbPath, size, mode); } else { thumbnail = QContentFactory::thumbnail(content, size, mode); } if (thumbnail.isNull()) { if (QIODevice *device = content.open()) { QImageReader reader(device); if (reader.canRead()) { QSize scaledSize = reader.size(); reader.setQuality(25); if (scaledSize.width() > 128 || scaledSize.height() > 128) { scaledSize.scale(QSize(128, 128), Qt::KeepAspectRatio); reader.setQuality( 49 ); // Otherwise Qt smooth scales reader.setScaledSize(scaledSize); reader.read(&thumbnail); if (!thumbnail.isNull()) { QImageWriter writer(thumbPath, QByteArray::fromRawData("PNG", 3)); writer.setQuality(25); writer.write(thumbnail); if (size.isValid()) thumbnail = thumbnail.scaled(size, mode); } } else { if (size.isValid()) { scaledSize.scale(size, mode); reader.setQuality( 49 ); // Otherwise Qt smooth scales reader.setScaledSize(scaledSize); } reader.read(&thumbnail); } } delete device; } } if (thumbnail.isNull() && content.type().startsWith(m_audioPrefix)) { QDir dir = QFileInfo(content.fileName()).absoluteDir(); foreach (const QString &fileName, m_folderThumbnails) { if (dir.exists(fileName)) { thumbnail = readThumbnail(dir.absoluteFilePath(fileName), size, mode); break; } } }