plugin/cim: respect image fill mode

Also prevent duplicate sha calcs
This commit is contained in:
2 * r + 2 * t 2025-08-30 16:58:26 +10:00
parent d22576ee82
commit 6ce97df535
2 changed files with 41 additions and 22 deletions

View file

@ -7,7 +7,7 @@
#include <QThreadPool> #include <QThreadPool>
#include <QFile> #include <QFile>
#include <QDir> #include <QDir>
#include <QImageReader> #include <QPainter>
qreal CachingImageManager::effectiveScale() const { qreal CachingImageManager::effectiveScale() const {
if (m_item->window()) { if (m_item->window()) {
@ -93,14 +93,22 @@ void CachingImageManager::updateSource() {
} }
void CachingImageManager::updateSource(const QString& path) { void CachingImageManager::updateSource(const QString& path) {
if (path.isEmpty()) { if (path.isEmpty() || path == m_shaPath) {
// Path is empty or already calculating sha for path
return; return;
} }
m_shaPath = path;
QThreadPool::globalInstance()->start([path, this] { QThreadPool::globalInstance()->start([path, this] {
const QString sha = sha256sum(path); const QString sha = sha256sum(path);
QMetaObject::invokeMethod(this, [path, sha, this]() { QMetaObject::invokeMethod(this, [path, sha, this]() {
if (m_path != path) {
// Path has changed, ignore
return;
}
int width = effectiveWidth(); int width = effectiveWidth();
int height = effectiveHeight(); int height = effectiveHeight();
const QString filename = QString("%1@%2x%3.png").arg(sha).arg(width).arg(height); const QString filename = QString("%1@%2x%3.png").arg(sha).arg(width).arg(height);
@ -126,6 +134,11 @@ void CachingImageManager::updateSource(const QString& path) {
m_item->setProperty("source", QUrl::fromLocalFile(path)); m_item->setProperty("source", QUrl::fromLocalFile(path));
createCache(path, cache.toLocalFile(), QSize(width, height)); createCache(path, cache.toLocalFile(), QSize(width, height));
} }
// Clear current running sha if same
if (m_shaPath == path) {
m_shaPath = QString();
}
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
}); });
} }
@ -135,33 +148,37 @@ QUrl CachingImageManager::cachePath() const {
} }
void CachingImageManager::createCache(const QString& path, const QString& cache, const QSize& size) const { void CachingImageManager::createCache(const QString& path, const QString& cache, const QSize& size) const {
QThreadPool::globalInstance()->start([path, cache, size] { QString fillMode = m_item->property("fillMode").toString();
QImageReader reader(path);
QSize imgSize = reader.size(); QThreadPool::globalInstance()->start([fillMode, path, cache, size] {
if (!imgSize.isValid()) { QImage image(path);
qWarning() << "CachingImageManager::createCache: unable to get size of" << path;
return;
}
qreal scale = std::max(
qreal(size.width()) / imgSize.width(),
qreal(size.height()) / imgSize.height()
);
QSizeF scaledSize(imgSize.width() * scale, imgSize.height() * scale);
qreal xOff = (scaledSize.width() - size.width()) / 2.0;
qreal yOff = (scaledSize.height() - size.height()) / 2.0;
reader.setScaledSize(scaledSize.toSize());
reader.setScaledClipRect(QRectF(xOff, yOff, size.width(), size.height()).toRect());
QImage image = reader.read();
if (image.isNull()) { if (image.isNull()) {
qWarning() << "CachingImageManager::createCache: failed to read" << path; qWarning() << "CachingImageManager::createCache: failed to read" << path;
return; return;
} }
image.convertTo(QImage::Format_ARGB32);
if (fillMode == "PreserveAspectCrop") {
image = image.scaled(size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
} else if (fillMode == "PreserveAspectFit") {
image = image.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
} else {
image = image.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
}
if (fillMode == "PreserveAspectCrop" || fillMode == "PreserveAspectFit") {
QImage canvas(size, QImage::Format_ARGB32);
canvas.fill(Qt::transparent);
QPainter painter(&canvas);
painter.drawImage((size.width() - image.width()) / 2, (size.height() - image.height()) / 2, image);
painter.end();
image = canvas;
}
const QString parent = QFileInfo(cache).absolutePath(); const QString parent = QFileInfo(cache).absolutePath();
if (!QDir().mkpath(parent) || !image.save(cache)) { if (!QDir().mkpath(parent) || !image.save(cache)) {
qWarning() << "CachingImageManager::createCache: failed to save to" << cache; qWarning() << "CachingImageManager::createCache: failed to save to" << cache;

View file

@ -40,6 +40,8 @@ signals:
void usingCacheChanged(); void usingCacheChanged();
private: private:
QString m_shaPath;
QQuickItem* m_item; QQuickItem* m_item;
QUrl m_cacheDir; QUrl m_cacheDir;