[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());