На этом шаге рассмотрим использование режима совмещения.
Под режимом совмещения понимается то, как должны совмещаться пиксел источника с целевым пикселом при рисовании. Пикселы могут иметь уровень прозрачности.
Этот механизм применяется для всех операций рисования, включая кисть, перо, градиенты и растровые изображения. Возможные операции проиллюстрированы на рис. 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(); }
Файлы приложения можно взять здесь.
На следующем шаге рассмотрим графические эффекты.