0

I'm trying to draw a high resolution image when device pixel ratio is set to 2x (to display nicely on a 4K monitor). It works fine if I draw a pixmap directly on a painter:

int pixelRatio = 2;
QPixmap myImage = ...;
auto pxm = myImage.scaled(imgDiameter * pixelRatio, imgDiameter * pixelRatio, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
pxm.setDevicePixelRatio(pixelRatio);
painter->drawPixmap(QPoint(xPos, yPos), pxm);

However since I need images to be drawn on top of irregular shapes I use the brush:

int pixelRatio = 2;
QPixmap myImage = ...;
auto oldBrush = painter->brush();
auto pxm = myImage.scaled(imgDiameter * pixelRatio, imgDiameter * pixelRatio, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
pxm.setDevicePixelRatio(pixelRatio);
QBrush brush(pxm);
painter->setPen(Qt::NoPen);
painter->setBrush(brush);
painter->setBrushOrigin(xPos, yPos);
painter->drawEllipse(xPos, yPos, imgDiameter, imgDiameter);
painter->setBrush(oldBrush);

When the brush is getting filled it appears that it doesn't adhere to pixmap's devicePixelRatio, so the pixmap inside the shape is twice as big.

Is there something wrong with what I'm doing?

pullo_van
  • 649
  • 6
  • 19

2 Answers2

0

You first need draw on pixmap what you want, then set needed device pixel ratio for pixmap, and then draw this pixmap

 if (pix.devicePixelRatio() == 2.0) {
        QPixmap output(pix.size());
        output.fill(Qt::transparent);
        QPainter pixPainter(&output);

        pixPainter.setBrush(pix);
        pixPainter.setPen(Qt::transparent);
        pixPainter.setRenderHint(QPainter::Antialiasing);
        QPainterPath path;
        path.add(...);
        ...
        pixPainter.drawPath(path);
        output.setDevicePixelRatio(pix.devicePixelRatio());
        painter.drawPixmap(0,0,output);
    }
Dzybba
  • 26
  • 2
0

QBrush allows to set a transformation matrix, so you can use scaling with a factor of 1/devicePixelRatio.

QTransform trans;
auto brushRatio = 1.f / pixelRatio;
trans.scale(brushRatio, brushRatio);
brush.setTransform(trans);

For your code it looks like

int pixelRatio = 2;
QPixmap myImage = ...;
auto oldBrush = painter->brush();
auto pxm = myImage.scaled(imgDiameter * pixelRatio, imgDiameter * pixelRatio, 
Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
QBrush brush(pxm);

QTransform trans;
auto brushRatio = 1.f / pixelRatio;
trans.scale(brushRatio, brushRatio);
brush.setTransform(trans);

painter->setPen(Qt::NoPen);
painter->setBrush(brush);
painter->setBrushOrigin(xPos, yPos);
painter->drawEllipse(xPos, yPos, imgDiameter, imgDiameter);
painter->setBrush(oldBrush);