Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QPainter::drawImage draws images in different places depending on image format



  • When drawing two images of the same size in the same place, the images don't actually appear in the same place if one of them is premultiplied and the other isn't. Here's a code sample to reproduce the issue.

    #include <QtGui/qpainter.h>
    #include <QtWidgets/qscrollarea.h>
    #include <QtWidgets/qmainwindow.h>
    #include <QtWidgets/qapplication.h>
    
    const int imageScale = 50;
    const QSize imageSize = {100, 100};
    const QImage::Format bottomFormat = QImage::Format_ARGB32;
    const QImage::Format topFormat = QImage::Format_ARGB32_Premultiplied;
    const QRgb bottomColor = qRgba(255, 0, 0, 127);
    const QRgb topColor = qPremultiply(qRgba(0, 0, 255, 127));
    
    class TestWidget final : public QWidget {
    public:
      explicit TestWidget(QWidget *parent)
        : QWidget{parent} {
        setFixedSize(imageSize * imageScale);
        
        bottom = QImage{imageSize, bottomFormat};
        top = QImage{imageSize, topFormat};
        
        const QPoint pos = {imageSize.width() - 2, imageSize.height() - 2};
        bottom.fill(0);
        bottom.setPixel(pos, bottomColor);
        top.fill(0);
        top.setPixel(pos, topColor);
      }
    
    private:
      QImage bottom;
      QImage top;
    
      void paintEvent(QPaintEvent *) override {
        QPainter painter{this};
        painter.fillRect(rect(), Qt::white);
        painter.drawImage(rect(), bottom);
        painter.drawImage(rect(), top);
      }
    };
    
    int main(int argc, char **argv) {
      QApplication app{argc, argv};
      QMainWindow window;
      window.resize(600, 600);
    
      auto *area = new QScrollArea{&window};
      auto *widget = new TestWidget{area};
      area->setWidget(widget);
      window.setCentralWidget(area);
      
      window.show();
      return app.exec();
    }
    

    Here's a screenshot that shows what I'm talking about.

    Screen Shot 2020-06-14 at 15.02.08.png

    I'm not sure why the scroll bars are messed up but I'm not concerned about that. The top image is not drawn in the same place as the bottom image. If the code sample is edited so that both images are the same format, the problem disappears.

    What's going on here? Should I create a bug report?


  • Lifetime Qt Champion

    @Kerndog73 said in QPainter::drawImage draws images in different places depending on image format:

    if one of them is premultiplied

    What do you mean by "premultiplied"?
    What does top.isNull() return?



  • By "premultiplied", I mean if one of them is QImage::Format_ARGB32_Premultiplied and the other is QImage::Format_ARGB32. From the screenshot, you can see that both images are being painted, but in different places for some reason.



  • Forgot to mention that I opened a bug report.


  • Lifetime Qt Champion

    Please provide a minimal compilable example on the report so that developers can more easily reproduce your issue.



  • @SGaist I did...


  • Lifetime Qt Champion

    Sorry, I had an issue with the list of objects attached to the report and did not see the .cpp file.

    Thanks for the report.


Log in to reply