From b5b5faa5eceba4c5ad0508cc0c079e6bad73b025 Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris Date: Wed, 1 Aug 2018 21:10:03 +0300 Subject: [PATCH] Consider the scale ratio when scaling down images fixes #393 --- src/Utils.cpp | 32 +++++++++++++++++++++++++++- src/Utils.h | 28 ++---------------------- src/dialogs/ImageOverlay.cpp | 2 +- src/dialogs/PreviewUploadOverlay.cpp | 2 +- src/timeline/widgets/ImageItem.cpp | 4 ++-- 5 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/Utils.cpp b/src/Utils.cpp index e4ca92d6..35dc3b88 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -223,11 +223,41 @@ utils::scaleImageToPixmap(const QImage &img, int size) return QPixmap(); const double sz = - ceil(QApplication::desktop()->screen()->devicePixelRatioF() * (double)size); + std::ceil(QApplication::desktop()->screen()->devicePixelRatioF() * (double)size); return QPixmap::fromImage( img.scaled(sz, sz, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } +QPixmap +utils::scaleDown(uint64_t maxWidth, uint64_t maxHeight, const QPixmap &source) +{ + if (source.isNull()) + return QPixmap(); + + const double pixelRatio = QApplication::desktop()->screen()->devicePixelRatioF(); + + // Take into account the scale factor of the screen. + maxWidth = std::ceil(pixelRatio * (double)maxWidth); + maxHeight = std::ceil(pixelRatio * (double)maxHeight); + + const double widthRatio = (double)maxWidth / (double)source.width(); + const double heightRatio = (double)maxHeight / (double)source.height(); + const double minAspectRatio = std::min(widthRatio, heightRatio); + + // Size of the output image. + int w, h = 0; + + if (minAspectRatio > 1) { + w = source.width(); + h = source.height(); + } else { + w = source.width() * minAspectRatio; + h = source.height() * minAspectRatio; + } + + return source.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); +} + QString utils::mxcToHttp(const QUrl &url, const QString &server, int port) { diff --git a/src/Utils.h b/src/Utils.h index 7132f2ab..7f544835 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -116,32 +116,8 @@ createDescriptionInfo(const Event &event, const QString &localUser, const QStrin } //! Scale down an image to fit to the given width & height limitations. -template -ImageType -scaleDown(uint64_t max_width, uint64_t max_height, const ImageType &source) -{ - if (source.isNull()) - return QPixmap(); - - auto width_ratio = (double)max_width / (double)source.width(); - auto height_ratio = (double)max_height / (double)source.height(); - - auto min_aspect_ratio = std::min(width_ratio, height_ratio); - - int final_width = 0; - int final_height = 0; - - if (min_aspect_ratio > 1) { - final_width = source.width(); - final_height = source.height(); - } else { - final_width = source.width() * min_aspect_ratio; - final_height = source.height() * min_aspect_ratio; - } - - return source.scaled( - final_width, final_height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); -} +QPixmap +scaleDown(uint64_t maxWidth, uint64_t maxHeight, const QPixmap &source); //! Delete items in a container based on a predicate. template diff --git a/src/dialogs/ImageOverlay.cpp b/src/dialogs/ImageOverlay.cpp index 7773f97c..b40aa164 100644 --- a/src/dialogs/ImageOverlay.cpp +++ b/src/dialogs/ImageOverlay.cpp @@ -68,7 +68,7 @@ ImageOverlay::paintEvent(QPaintEvent *event) int max_width = screen_.width() - 2 * outer_margin; int max_height = screen_.height(); - image_ = utils::scaleDown(max_width, max_height, originalImage_); + image_ = utils::scaleDown(max_width, max_height, originalImage_); int diff_x = max_width - image_.width(); int diff_y = max_height - image_.height(); diff --git a/src/dialogs/PreviewUploadOverlay.cpp b/src/dialogs/PreviewUploadOverlay.cpp index 31167727..82366f1a 100644 --- a/src/dialogs/PreviewUploadOverlay.cpp +++ b/src/dialogs/PreviewUploadOverlay.cpp @@ -108,7 +108,7 @@ PreviewUploadOverlay::init() const auto maxHeight = winsize.height() * 0.8; // Scale image preview to fit into the application window. - infoLabel_.setPixmap(utils::scaleDown(maxWidth, maxHeight, image_)); + infoLabel_.setPixmap(utils::scaleDown(maxWidth, maxHeight, image_)); move(center.x() - (width() * 0.5), center.y() - (height() * 0.5)); } else { infoLabel_.setAlignment(Qt::AlignLeft); diff --git a/src/timeline/widgets/ImageItem.cpp b/src/timeline/widgets/ImageItem.cpp index 19b445db..b66b82ae 100644 --- a/src/timeline/widgets/ImageItem.cpp +++ b/src/timeline/widgets/ImageItem.cpp @@ -126,7 +126,7 @@ void ImageItem::setImage(const QPixmap &image) { image_ = image; - scaled_image_ = utils::scaleDown(max_width_, max_height_, image_); + scaled_image_ = utils::scaleDown(max_width_, max_height_, image_); width_ = scaled_image_.width(); height_ = scaled_image_.height(); @@ -165,7 +165,7 @@ ImageItem::resizeEvent(QResizeEvent *event) if (!image_) return QWidget::resizeEvent(event); - scaled_image_ = utils::scaleDown(max_width_, max_height_, image_); + scaled_image_ = utils::scaleDown(max_width_, max_height_, image_); width_ = scaled_image_.width(); height_ = scaled_image_.height();