Как использовать маску с QPainter? - PullRequest
14 голосов
/ 24 сентября 2011

У меня есть фигура (синего цвета), загруженная из PNG с прозрачностью:

enter image description here

Затем я рисую несколько кругов поверх этой фигуры (красным) с помощьюQPainter::drawEllipse.

enter image description here

Результат несколько напоминает третью картинку с красной формой, полностью закрывающей синюю:

enter image description here

Однако я хотел бы, чтобы синяя фигура действовала как маска для красной, с таким результатом:

enter image description here

Возможно лисделать это с QPainter?

1 Ответ

25 голосов
/ 24 сентября 2011

Это возможно.Предполагая, что вы загружаете свой PNG в QImage, вы можете сделать что-то вроде этого, чтобы создать маску из вашего изображения:

QImage img("your.png");
QPixmap mask = QPixmap::fromImage(img.createAlphaMask());

См. Другие функции create*Mask в QImage для альтернатив.

Тогда достаточно просто установить область клипа художника:

QPainter p(this);
p.setClipRegion(QRegion(mask));

Вот глупая демонстрация (не используйте этот код как есть, загрузка изображений, маска и создание области должны быть кэшированы., они потенциально дороги):

#include <QtGui>

class W: public QWidget
{
    Q_OBJECT
    public:
        W(): QWidget(0) { }

    protected:
        void paintEvent(QPaintEvent *)
        {
            QPainter p(this);
            QImage img("../back.png");
            QPixmap mask = QPixmap::fromImage(img.createAlphaMask());

            // draw the original image on the right
            p.drawImage(300, 0, img);

            // draw some ellipses in the middle
            p.setBrush(Qt::red);
            for (int i=0; i<100; i+=10)
                p.drawEllipse(i+150, i, 20, 70);

            // and do the same thing, but with the mask active
            p.setClipRegion(QRegion(mask));
            for (int i=0; i<100; i+=10)
                p.drawEllipse(i, i, 20, 70);
        }
};

, который производит что-то вроде этого: enter image description here

...