Шаг 213.
Библиотека Qt.
Режим совмещения

    На этом шаге рассмотрим использование режима совмещения.

    Под режимом совмещения понимается то, как должны совмещаться пиксел источника с целевым пикселом при рисовании. Пикселы могут иметь уровень прозрачности.

    Этот механизм применяется для всех операций рисования, включая кисть, перо, градиенты и растровые изображения. Возможные операции проиллюстрированы на рис. 1.


Рис.1. Пример режимов совмещения

    Режим совмещения устанавливается с помощью метода QPainter::setCompositionMode(). По умолчанию режимом совмещения является "источник сверху" QPainter::CompositionMode _SourceOver. Если вам понадобится прохождение по пикселам растрового изображения, чтобы манипулировать альфа-каналом или цветовыми значениями, то прежде всего проверьте, нет ли для решения вашей задачи подходящего режима совмещения.

/*Функция lbl() предназначена для создания виджетов надписей
с установленными растровыми изображениями, иллюстрирующими результат
определенной операции совмещения*/
QLabel* lbl(const QPainter::CompositionMode& mode)
{
    QLabel* plbl = new QLabel;
    //методом setFixedSize() устанавливается неизменяемый размер,
    plbl->setFixedSize(100, 100);
    /*который впоследствии служит для инициализации объекта прямоугольной
    области rect*/
    QRect    rect(plbl->contentsRect());
    QPainter painter;
    /*объект rect используется для задания размеров исходного
    (sourceImage) объекта растрового изображения*/
    QImage sourceImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
    painter.begin(&sourceImage);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(QColor(250,255,0));
    painter.setBrush(QBrush(QColor(250, 255, 0)));
    //рисуем треугольник желтого цвета
    painter.drawPolygon(QPolygon() << rect.topLeft()
                                   << rect.topRight()
                                   << rect.bottomRight()
                        );
    painter.end();
    /*объект rect используется для задания размеров результирующего
    (resultImage) объекта растрового изображения*/
    QImage resultImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
    painter.begin(&resultImage);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.setPen(QColor(255, 0, 250));
    painter.setBrush(QBrush(QColor(255, 0, 250)));
    //рисуем треугольник пурпурного цвета
    painter.drawPolygon(QPolygon() << rect.topLeft()
                                   << rect.topRight()
                                   << rect.bottomLeft()
                        );
    /*методом QPainter::setCompositeMode() устанавливается
    режим совмещения, переданный в функцию lbl() в переменной mode*/
    painter.setCompositionMode(mode);
    /*растровое (sourceImage) изображение рисуется в результирующем
    изображении методом QPainter::drawImage()*/
    painter.drawImage(rect, sourceImage);
    painter.end();
    //устанавливаем результирующее растровое изображение в виджете надписи
    plbl->setPixmap(QPixmap::fromImage(resultImage));
    //возвращаем указатель на созданный виджет надписи
    return plbl;
}
/*создаются виджеты надписей с изображениями (вызовы функций lbl())
и поясняющими надписями, описывающими примененный режим совмещения.
Все элементы размещаются при помощи менеджеров компоновки (layout)
табличного размещения (pgrd) на поверхности виджета (wgt)*/
int main(int argc, char** argv)
{
   QApplication app(argc, argv);
   app.setApplicationDisplayName("Режим совмещения");
   QWidget      wgt;
   QGridLayout* pgrd = new QGridLayout;
   pgrd->addWidget(lbl(QPainter::CompositionMode_Source), 0, 0);
   pgrd->addWidget(new QLabel("<CENTER>Source</CENTER>"), 1, 0);
   pgrd->addWidget(lbl(QPainter::CompositionMode_SourceOver), 0, 1);
   pgrd->addWidget(new QLabel("<CENTER>SourceOver</CENTER>"), 1, 1);
   pgrd->addWidget(lbl(QPainter::CompositionMode_SourceIn), 0, 2);
   pgrd->addWidget(new QLabel("<CENTER>SourceIn</CENTER>"), 1, 2);
   pgrd->addWidget(lbl(QPainter::CompositionMode_SourceOut), 0, 3);
   pgrd->addWidget(new QLabel("<CENTER>SourceOut</CENTER>"), 1, 3);
   pgrd->addWidget(lbl(QPainter::CompositionMode_SourceAtop), 0, 4);
   pgrd->addWidget(new QLabel("<CENTER>SourceAtop</CENTER>"), 1, 4);
   pgrd->addWidget(lbl(QPainter::CompositionMode_Clear), 0, 5);
   pgrd->addWidget(new QLabel("<CENTER>Clear</CENTER>"), 1, 5);
   pgrd->addWidget(lbl(QPainter::CompositionMode_Destination), 2, 0);
   pgrd->addWidget(new QLabel("<CENTER>Destination</CENTER>"), 3, 0);
   pgrd->addWidget(lbl(QPainter::CompositionMode_DestinationOver), 2, 1);
   pgrd->addWidget(new QLabel("<CENTER>DestinationOver</CENTER>"), 3, 1);
   pgrd->addWidget(lbl(QPainter::CompositionMode_DestinationIn), 2, 2);
   pgrd->addWidget(new QLabel("<CENTER>DestinationIn</CENTER>"), 3, 2);
   pgrd->addWidget(lbl(QPainter::CompositionMode_DestinationOut), 2, 3);
   pgrd->addWidget(new QLabel("<CENTER>DestinationOut</CENTER>"), 3, 3);
   pgrd->addWidget(lbl(QPainter::CompositionMode_DestinationAtop), 2, 4);
   pgrd->addWidget(new QLabel("<CENTER>DestinationAtop</CENTER>"), 3, 4);
   pgrd->addWidget(lbl(QPainter::CompositionMode_Xor), 2, 5);
   pgrd->addWidget(new QLabel("<CENTER>Xor</CENTER>"), 3, 5);
   wgt.setLayout(pgrd);
   wgt.show();
   return app.exec();
}

    Файлы приложения можно взять здесь.

    На следующем шаге рассмотрим графические эффекты.




Предыдущий шаг Содержание Следующий шаг