Search code examples
c++qtqpainter

QPainter composition mode example does not work as expected


I'm stuck with the difference from the book example and my version of it. Qt version 5.12.0

As it's shown in the example:

enter image description here

As I see from my output:

enter image description here

First, destination and source In/Atop modes have not the same pictures. And, another noticed thing is, that we can see the rectangle as an additional layer between two.

Code to create the label:

QLabel* lblCreate(const QPainter::CompositionMode& mode){
    QLabel* lbl = new QLabel;
    lbl->setFixedSize(100, 100);

    QRect rect(lbl->contentsRect());
    QPainter painter;
    // create first image
    QImage sourceImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
    painter.begin(&sourceImage);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setBrush(QColor(0, 255, 0));
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    // draw triangle
    painter.drawPolygon(QPolygon() << rect.bottomLeft()
                                   << QPoint(rect.center().x(), 0)
                                   << rect.bottomRight());
    painter.end();
    // create second image
    QImage resultImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
    painter.begin(&resultImage);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(QPen(QColor(0, 255, 0), 4));
    painter.setBrush(QColor(255, 0, 0));
    // draw circle
    painter.drawEllipse(rect);
    painter.setCompositionMode(mode);
    painter.drawImage(rect, sourceImage);
   painter.end();

    lbl->setPixmap(QPixmap::fromImage(resultImage));
    return lbl;}

How it creates in main.cpp:

innerLayout_2->addWidget(lblCreate(QPainter::CompositionMode_Source), 0, 0);
innerLayout_2->addWidget(new QLabel("<CENTER>Source</CENTER>"), 1, 0);

My own suspicion is it may be depend on QImage::Format_ARGB32_Premultiplied. Or it's mine handmade bug.

Anyway, I would be grateful for any ideas.

Thnx in advance!


Solution

  • The composition mode works on transparent backgrounds, in your case it is not, so you must set it before painting, for this you could use the fill() method:

    QImage sourceImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
    sourceImage.fill(Qt::transparent);
    
    QImage resultImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
    resultImage.fill(Qt::transparent);