From 7741bb33b21da53844b35f6ca843df61e462d288 Mon Sep 17 00:00:00 2001 From: Andre Rummler Date: Sat, 5 Sep 2026 19:27:17 +0200 Subject: [PATCH] Use downscaled image for image transparency window to improve resposiveness. --- sources/ui/imagetransparentcolordialog.cpp | 24 ++++++++++++++-------- sources/ui/imagetransparentcolordialog.h | 13 ++++++++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/sources/ui/imagetransparentcolordialog.cpp b/sources/ui/imagetransparentcolordialog.cpp index 62bcf8813..0cc45d335 100644 --- a/sources/ui/imagetransparentcolordialog.cpp +++ b/sources/ui/imagetransparentcolordialog.cpp @@ -48,10 +48,10 @@ ClickableImageLabel::ClickableImageLabel(const QImage &sourceImage, QWidget *par const qreal scaleH = qreal(MAX_DISPLAY_SIZE) / m_source.height(); m_displayScale = qMin(qreal(1.0), qMin(scaleW, scaleH)); // never upscale a small image, only ever shrink a large one - const QImage displayImage = (m_displayScale < 1.0) + m_displayImage = (m_displayScale < 1.0) ? m_source.scaled(m_source.size() * m_displayScale, Qt::KeepAspectRatio, Qt::SmoothTransformation) : m_source; - setPixmap(QPixmap::fromImage(displayImage)); + setPixmap(QPixmap::fromImage(m_displayImage)); setCursor(Qt::CrossCursor); setToolTip(tr("Cliquez pour choisir une couleur")); } @@ -101,6 +101,7 @@ ImageTransparentColorDialog::ImageTransparentColorDialog(const QPixmap &basePixm setWindowTitle(tr("Couleur transparente")); m_sourceLabel = new ClickableImageLabel(m_sourceImage, this); + m_previewSourceImage = m_sourceLabel->displayImage(); m_previewLabel = new QLabel(this); m_hintLabel = new QLabel(this); @@ -232,15 +233,22 @@ void ImageTransparentColorDialog::onToleranceChanged(int value) /** @brief ImageTransparentColorDialog::updatePreview Recomputes the checkerboard-backed preview against the current set - of picked colours and the shared tolerance. Always runs against - m_sourceImage (the original, full-resolution image), not any - already-keyed result -- so adjusting the tolerance, or adding or - removing a colour, re-evaluates every picked colour from scratch - each time rather than compounding successive passes. + of picked colours and the shared tolerance. Runs against + m_previewSourceImage (the same downsampled copy ClickableImageLabel + already computed for its own display, not the full-resolution + m_sourceImage) -- this fires on every tolerance slider tick, not + just on release, and a full-resolution O(width*height*colours) pass + per tick was visibly laggy on a large source image. resultPixmap(), + below, still computes the final, committed result at full + resolution -- only this live preview is downsampled. Always + re-evaluates every picked colour from scratch against + m_previewSourceImage, not any already-keyed result, so adjusting + the tolerance or adding/removing a colour never compounds successive + passes. */ void ImageTransparentColorDialog::updatePreview() { - const QImage keyed = applyColorKey(m_sourceImage, m_pickedColors, m_tolerance); + const QImage keyed = applyColorKey(m_previewSourceImage, m_pickedColors, m_tolerance); m_previewLabel->setPixmap(onCheckerboard(keyed)); } diff --git a/sources/ui/imagetransparentcolordialog.h b/sources/ui/imagetransparentcolordialog.h index 691983057..c6b7d11a3 100644 --- a/sources/ui/imagetransparentcolordialog.h +++ b/sources/ui/imagetransparentcolordialog.h @@ -45,6 +45,17 @@ class ClickableImageLabel : public QLabel public: explicit ClickableImageLabel(const QImage &sourceImage, QWidget *parent = nullptr); + /// The same downsampled image already computed for display -- + /// reused as the live-preview source so a tolerance drag runs + /// its per-tick colour-key pass against a small image instead + /// of the full-resolution one, which on a large source (a + /// scanned schematic background, several Mpx) made every + /// intermediate slider tick visibly lag. resultPixmap() still + /// computes the final, committed result from the true + /// full-resolution source -- only the live preview is + /// downsampled. + QImage displayImage() const { return m_displayImage; } + signals: void colorPicked(const QColor &color); @@ -53,6 +64,7 @@ class ClickableImageLabel : public QLabel private: QImage m_source; + QImage m_displayImage; qreal m_displayScale = 1.0; }; @@ -119,6 +131,7 @@ class ImageTransparentColorDialog : public QDialog static QPixmap onCheckerboard(const QImage &image); QImage m_sourceImage; + QImage m_previewSourceImage; // downsampled -- see ClickableImageLabel::displayImage()'s comment for why QList m_pickedColors; int m_tolerance = 10;