[graphics/krita] libs/ui: Fix rotation. Fix zoom inaccuracies by switching to full size QImage instead of small scale mimap

Emmet O'Neill <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit c815478eaae7b528c084dfaf27c8fa7b072425df by Emmet O'Neill, on behalf of Le Tien Dat.
Committed on 13/08/2026 at 23:16.
Pushed by emmetoneill into branch 'master'.

Fix rotation. Fix zoom inaccuracies by switching to full size QImage instead of small scale mimap

M  +26   -6    libs/ui/KisReferenceImage.cpp
M  +4    -0    libs/ui/KisReferenceImage.h
M  +12   -13   libs/ui/tool/KisAsyncColorSamplerHelper.cpp

https://invent.kde.org/graphics/krita/-/commit/c815478eaae7b528c084dfaf27c8fa7b072425df

diff --git a/libs/ui/KisReferenceImage.cpp b/libs/ui/KisReferenceImage.cpp
index 882bc8cef7e..bbde5eb32e0 100644
--- a/libs/ui/KisReferenceImage.cpp
+++ b/libs/ui/KisReferenceImage.cpp
@@ -99,12 +99,14 @@ struct KisReferenceImage::Private : public QSharedData
 #else
         image.convertToColorSpace(QColorSpace(QColorSpace::SRgb));
 #endif
+        // It should be ok to covert to ARGB as it's saved as PNG anyways?
+        image.convertTo(QImage::Format_ARGB32);
 
         return (!image.isNull());
     }
 
     bool loadFromQImage(const QImage &img) {
-        image = img;
+        image = img.convertToFormat(QImage::Format_ARGB32);
         return !image.isNull();
     }
 
@@ -348,17 +350,28 @@ void KisReferenceImage::setFilename(const QString &filename)
     d->externalFilename = filename;
 }
 
+<<<<<<< HEAD
 KoColor KisReferenceImage::getPixel(QPointF position)
+=======
+QPoint KisReferenceImage::documentToPixel(const QPointF &docPoint)
+{
+    QSizeF shapeSize = size();
+    QTransform scale = QTransform::fromScale(d->image.width() / shapeSize.width(), d->image.height() / shapeSize.height());
+
+    QTransform transform = absoluteTransformation().inverted() * scale;
+    QPointF localPosition = docPoint * transform;
+
+    return localPosition.toPoint();
+}
+
+QColor KisReferenceImage::getPixel(QPointF position)
+>>>>>>> 208309fd88 (Fix rotation. Fix zoom inaccuracies by switching to full size QImage instead of small scale mimap)
 {
     KoColor transparent;
     transparent.setOpacity(0.0);
     if (transparency() == 1.0) return transparent;
 
-    const QSizeF shapeSize = size();
-    const QTransform scale = QTransform::fromScale(d->image.width() / shapeSize.width(), d->image.height() / shapeSize.height());
-
-    const QTransform transform = absoluteTransformation().inverted() * scale;
-    const QPointF localPosition = position * transform;
+    const QPointF localPosition = documentToPixel(position);
 
     if (d->cachedImage.isNull()) {
         d->updateCache();
@@ -484,6 +497,13 @@ QImage KisReferenceImage::getImage()
     return d->image;
 }
 
+QImage KisReferenceImage::getCachedImage()
+{
+    if (d->cachedImage.isNull()) d->updateCache();
+
+    return d->cachedImage;
+}
+
 KoShape *KisReferenceImage::cloneShape() const
 {
     return new KisReferenceImage(*this);
diff --git a/libs/ui/KisReferenceImage.h b/libs/ui/KisReferenceImage.h
index bae69b7fef4..a6ac3d1d354 100644
--- a/libs/ui/KisReferenceImage.h
+++ b/libs/ui/KisReferenceImage.h
@@ -76,6 +76,9 @@ public:
 
     KoColor getPixel(QPointF position);
 
+    QPoint documentToPixel(const QPointF &docPoint);
+    QColor getPixel(QPointF position);
+
     void saveXml(QDomDocument &document, QDomElement &parentElement, int id);
     bool saveImage(KoStore *store) const;
 
@@ -83,6 +86,7 @@ public:
     bool loadImage(KoStore *store);
 
     QImage getImage();
+    QImage getCachedImage();
 
 private:
     struct Private;
diff --git a/libs/ui/tool/KisAsyncColorSamplerHelper.cpp b/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
index 8ccb9d1b654..98c90e3d53d 100644
--- a/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
+++ b/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
@@ -600,7 +600,7 @@ void KisAsyncColorSamplerHelper::paintCircleCanvasPreview(QPainter &gc, const QR
     gc.setClipPath(QPainterPath(), Qt::NoClip);
 }
 
-// TODO: Fix incorrect preview position, weird wrapping stuff at edge of rotated ref image
+// TODO: Fix color sampler run away when REALLY zoomed in
 // Won't show opacity because the color sampled doesn't respect opacity either
 void KisAsyncColorSamplerHelper::paintCircleReferenceImagePreview(QPainter &gc, const QRectF &viewRectF, const QRectF &sampleDocRectF, const QPainterPath &clip) {
     KisDocument *doc = m_d->canvas->viewManager()->document();
@@ -619,26 +619,25 @@ void KisAsyncColorSamplerHelper::paintCircleReferenceImagePreview(QPainter &gc,
     });
     Q_FOREACH(KisReferenceImage *refImage, refList) {
         // Check if sampleRect intersect with reference image
-        QTransform refTf = refImage->absoluteTransformation();
-        QPolygonF outline = refTf.map(refImage->outlineRect());
+        QPolygonF outline = refImage->absoluteTransformation().map(refImage->outlineRect());
         if (!outline.intersects(QPolygonF(sampleDocRectF))) continue;
 
-        QRectF sampleRefRectF = refImage->documentToShape(sampleDocRectF);
+        QImage image = refImage->getCachedImage();
+        // image.convertTo(QImage::Format_ARGB32); Do this in KisReferenceImage to avoid having to copy? and convert
 
-        // TODO: Check if rounding like this actually OK. Probably not!
-        // This probably cause the ever so slighly off position
-        QPixmap refPixmap(refImage->size().toSize());
-        QPainter refPainter(&refPixmap);
-        refPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
-        refImage->paint(refPainter);
+        QPointF sampleRefPointF = refImage->documentToPixel(sampleDocRectF.center());
+        QRectF shapeRectF = refImage->documentToShape(sampleDocRectF);
+        qreal xScale = refImage->boundingRect().width() / image.width();
+        qreal yScale = refImage->boundingRect().height() / image.height();
+
+        QRectF sampleRefRectF = QRectF(sampleRefPointF, QSizeF(shapeRectF.width() / xScale, shapeRectF.height() / yScale));
+        sampleRefRectF.moveCenter(sampleRefPointF);
 
-        // Rotate the painter, draw, rotate back is seemingly easier than
-        // trying to rotate the pixmap and having to deal with sourceRect
         gc.translate(viewRectF.center());
         gc.rotate(refImage->rotation());
         gc.translate(-viewRectF.center());
 
-        gc.drawPixmap(viewRectF, refPixmap, sampleRefRectF);
+        gc.drawImage(viewRectF, image.copy(sampleRefRectF.toRect()));
 
         gc.translate(viewRectF.center());
         gc.rotate(-refImage->rotation());
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.