From 28adc9dc9b8a0197078830c55f90e1ce81f09b2a Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 26 Apr 2020 11:26:51 +0200 Subject: [PATCH] Respect exif rotation of images Sometimes thumbnails still have the wrong dimensions, as they are scaled to fit inside a rectange of the reported size in the image. Not sure, who is wrong there, the media repo or we. --- src/AvatarProvider.cpp | 8 ++++---- src/MxcImageProvider.cpp | 28 +++++++++++++++++++--------- src/Utils.cpp | 11 +++++++++++ src/Utils.h | 4 ++++ 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/AvatarProvider.cpp b/src/AvatarProvider.cpp index d0556f85..603bb71a 100644 --- a/src/AvatarProvider.cpp +++ b/src/AvatarProvider.cpp @@ -24,6 +24,7 @@ #include "Cache.h" #include "Logging.h" #include "MatrixClient.h" +#include "Utils.h" static QPixmapCache avatar_cache; @@ -44,7 +45,7 @@ resolve(const QString &avatarUrl, int size, QObject *receiver, AvatarCallback ca auto data = cache::image(cacheKey); if (!data.isNull()) { - pixmap.loadFromData(data); + pixmap = QPixmap::fromImage(utils::readImage(&data)); avatar_cache.insert(cacheKey, pixmap); callback(pixmap); return; @@ -54,9 +55,8 @@ resolve(const QString &avatarUrl, int size, QObject *receiver, AvatarCallback ca QObject::connect(proxy.get(), &AvatarProxy::avatarDownloaded, receiver, - [callback, cacheKey](const QByteArray &data) { - QPixmap pm; - pm.loadFromData(data); + [callback, cacheKey](QByteArray data) { + QPixmap pm = QPixmap::fromImage(utils::readImage(&data)); avatar_cache.insert(cacheKey, pm); callback(pm); }); diff --git a/src/MxcImageProvider.cpp b/src/MxcImageProvider.cpp index d04eab24..8e67375d 100644 --- a/src/MxcImageProvider.cpp +++ b/src/MxcImageProvider.cpp @@ -3,6 +3,7 @@ #include "Cache.h" #include "Logging.h" #include "MatrixClient.h" +#include "Utils.h" void MxcImageResponse::run() @@ -14,11 +15,15 @@ MxcImageResponse::run() .arg(m_requestedSize.height()); auto data = cache::image(fileName); - if (!data.isNull() && m_image.loadFromData(data)) { + if (!data.isNull()) { + m_image = utils::readImage(&data); m_image = m_image.scaled(m_requestedSize, Qt::KeepAspectRatio); m_image.setText("mxc url", "mxc://" + m_id); - emit finished(); - return; + + if (!m_image.isNull()) { + emit finished(); + return; + } } mtx::http::ThumbOpts opts; @@ -39,17 +44,22 @@ MxcImageResponse::run() auto data = QByteArray(res.data(), res.size()); cache::saveImage(fileName, data); - m_image.loadFromData(data); + m_image = utils::readImage(&data); m_image.setText("mxc url", "mxc://" + m_id); emit finished(); }); } else { auto data = cache::image(m_id); - if (!data.isNull() && m_image.loadFromData(data)) { + + if (!data.isNull()) { + m_image = utils::readImage(&data); m_image.setText("mxc url", "mxc://" + m_id); - emit finished(); - return; + + if (!m_image.isNull()) { + emit finished(); + return; + } } http::client()->download( @@ -73,11 +83,11 @@ MxcImageResponse::run() mtx::crypto::decrypt_file(temp, m_encryptionInfo.value())); auto data = QByteArray(temp.data(), temp.size()); - m_image.loadFromData(data); + cache::saveImage(m_id, data); + m_image = utils::readImage(&data); m_image.setText("original filename", QString::fromStdString(originalFilename)); m_image.setText("mxc url", "mxc://" + m_id); - cache::saveImage(m_id, data); emit finished(); }); diff --git a/src/Utils.cpp b/src/Utils.cpp index cd615c24..f0a8d61b 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -1,9 +1,11 @@ #include "Utils.h" #include +#include #include #include #include +#include #include #include #include @@ -657,3 +659,12 @@ utils::restoreCombobox(QComboBox *combo, const QString &value) } } } + +QImage +utils::readImage(QByteArray *data) +{ + QBuffer buf(data); + QImageReader reader(&buf); + reader.setAutoTransform(true); + return reader.read(); +} diff --git a/src/Utils.h b/src/Utils.h index 663d5a38..d3f66246 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -306,4 +306,8 @@ centerWidget(QWidget *widget, QWidget *parent); void restoreCombobox(QComboBox *combo, const QString &value); + +//! Read image respecting exif orientation +QImage +readImage(QByteArray *data); }