QImage NemoThumbnailProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) { setupCache(); // needed for stupid things like gallery model, which pass us a url if (id.startsWith("file://")) { // qWarning() << Q_FUNC_INFO << "Removing file:// prefix, before: " << id; QString &nid = const_cast<QString &>(id); nid = nid.remove(0, 7); } TDEBUG() << Q_FUNC_INFO << "Requested image: " << id << " with size " << requestedSize; // sourceSize should indicate what size thumbnail you want. i.e. if you want a 120x120px thumbnail, // set sourceSize: Qt.size(120, 120). if (!requestedSize.isValid()) qFatal("You must request a sourceSize whenever you use nemoThumbnail"); if (size) *size = requestedSize; QByteArray hashData = cacheKey(id, requestedSize); QImage img = attemptCachedServe(id, hashData); if (!img.isNull()) { TDEBUG() << Q_FUNC_INFO << "Read " << id << " from cache"; return img; } return generateThumbnail(id, hashData, requestedSize); }
QImage FileThumbnailImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) { setupCache(); // needed for stupid things like gallery model, which pass us a url if (id.startsWith("file://")) { qWarning() << Q_FUNC_INFO << "Removing file:// prefix, before: " << id; QString &nid = const_cast<QString &>(id); nid = nid.remove(0, 7); } qDebug() << Q_FUNC_INFO << "Requested image: " << id << " with size " << requestedSize; // sourceSize should indicate what size thumbnail you want. i.e. if you want a 120x120px thumbnail, // set sourceSize: Qt.size(120, 120). if (!requestedSize.isValid()) qFatal("You must request a sourceSize whenever you use nemoThumbnail"); if (size) *size = requestedSize; QByteArray hashData = cacheKey(id, requestedSize); QImage img = attemptCachedServe(hashData); if (!img.isNull()) { qDebug() << Q_FUNC_INFO << "Read " << id << " from cache"; return img; } // cache couldn't satisfy us. // step 1: read source image in QImageReader ir(id); img = ir.read(); // don't pollute the cache with false positives if (img.isNull()) return QImage(); if (img.size() == requestedSize) return img; // step 2: scale to target size if (img.height() == img.width()) { // in the case of a squared image, there's no need to crop img = img.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); } else if (img.height() >= requestedSize.height() && img.width() >= requestedSize.width()) { // if the image is larger than the desired size (on both dimensions) // then crop, and scale down if (img.width() < img.height()) { int cropPosition = (img.height() - img.width()) / 2; img = img.copy(0, cropPosition, img.width(), img.width()); img = img.scaledToWidth(requestedSize.width(), Qt::SmoothTransformation); } else { int cropPosition = (img.width() - img.height()) / 2; img = img.copy(cropPosition, 0, img.height(), img.height()); img = img.scaledToHeight(requestedSize.height(), Qt::SmoothTransformation); } } else if ((img.width() <= requestedSize.width() && img.height() >= requestedSize.height()) || (img.width() >= requestedSize.width() && img.height() <= requestedSize.height())) { // if the image is smaller than the desired size on one dimension, scale it up, // then crop down to thumbnail size. if (img.width() <= requestedSize.width() && img.height() >= requestedSize.height()) { img = img.scaledToWidth(requestedSize.width(), Qt::SmoothTransformation); int cropPosition = (img.height() - img.width()) / 2; img = img.copy(0, cropPosition, img.width(), img.width()); } else { img = img.scaledToHeight(requestedSize.height(), Qt::SmoothTransformation); int cropPosition = (img.width() - img.height()) / 2; img = img.copy(cropPosition, 0, img.height(), img.height()); } } else { // if the image is smaller on both dimensions, scale it up, and use the requested // size to do the cropping if (img.width() < img.height()) { img = img.scaledToWidth(requestedSize.width(), Qt::SmoothTransformation); int cropPosition = (img.height() - requestedSize.height()) / 2; img = img.copy(0, cropPosition, img.width(), img.width()); } else { img = img.scaledToHeight(requestedSize.height(), Qt::SmoothTransformation); int cropPosition = (img.width() - requestedSize.width()) / 2; img = img.copy(cropPosition, 0, img.height(), img.height()); } } // step 3: write to cache for next time writeCacheFile(hashData, img); qDebug() << Q_FUNC_INFO << "Wrote " << id << " to cache"; return img; }