Auf dieser Seite

Beispiel für Bildkomposition

Zeigt, wie die Kompositionsmodi in „ QPainter “ funktionieren.

Anwendung, die zwei Bilder mithilfe von Mischmodi kombiniert

Einrichten der Ressourcendatei

Das Beispiel zur Bildkomposition erfordert zwei Quellbilder, „butterfly.png“ und „checker.png“, die in der Datei „imagecomposition.qrc“ eingebettet sind. Die Datei enthält den folgenden Code:

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
    <file>images/butterfly.png</file>
    <file>images/checker.png</file>
</qresource>
</RCC>

Weitere Informationen zu Ressourcendateien finden Sie unter „Das Qt-Ressourcensystem“.

Definition der Klasse `ImageComposer`

Die Klasse „ ImageComposer “ ist eine Unterklasse von „ QWidget “ und implementiert drei private Slots: „ chooseSource() “, „ chooseDestination() “ und „ recalculateResult() “.

class ImageComposer : public QWidget
{
    Q_OBJECT

public:
    ImageComposer();

private slots:
    void chooseSource();
    void chooseDestination();
    void recalculateResult();

Darüber hinaus besteht „ ImageComposer “ aus fünf privaten Funktionen: „ addOp() “, „ chooseImage() “, „ loadImage() “, „ currentMode() “ und „ imagePos() “ sowie aus privaten Instanzen von „ QToolButton “, „ QComboBox “, „ QLabel “ und „ QImage “.

private:
    void addOp(QPainter::CompositionMode mode, const QString &name);
    void chooseImage(const QString &title, QImage *image, QToolButton *button);
    void loadImage(const QString &fileName, QImage *image, QToolButton *button);
    QPainter::CompositionMode currentMode() const;
    QPoint imagePos(const QImage &image) const;

    QToolButton *sourceButton;
    QToolButton *destinationButton;
    QComboBox *operatorComboBox;
    QLabel *equalLabel;
    QLabel *resultLabel;

    QImage sourceImage;
    QImage destinationImage;
    QImage resultImage;
};

Implementierung der Klasse „ImageComposer“

Wir deklarieren ein „ QSize “-Objekt, „ resultSize “, als statische Konstante mit einer Breite und Höhe von jeweils 200.

static const QSize resultSize(200, 200);

Im Konstruktor instanziieren wir ein „ QToolButton “-Objekt, „ sourceButton “, und setzen dessen Eigenschaft „ iconSize “ auf „ resultSize “. Das „ operatorComboBox “ wird instanziiert und anschließend mithilfe der Funktion „ addOp() “ gefüllt. Diese Funktion akzeptiert „ QPainter::CompositionMode “, „ mode “ sowie „ QString “ und „ name “, die den Namen des Kompositionsmodus darstellen.

ImageComposer::ImageComposer()
{
    sourceButton = new QToolButton;
    sourceButton->setIconSize(resultSize);

    operatorComboBox = new QComboBox;
    addOp(QPainter::CompositionMode_SourceOver, tr("SourceOver"));
    addOp(QPainter::CompositionMode_DestinationOver, tr("DestinationOver"));
    addOp(QPainter::CompositionMode_Clear, tr("Clear"));
    addOp(QPainter::CompositionMode_Source, tr("Source"));
    addOp(QPainter::CompositionMode_Destination, tr("Destination"));
    addOp(QPainter::CompositionMode_SourceIn, tr("SourceIn"));
    addOp(QPainter::CompositionMode_DestinationIn, tr("DestinationIn"));
    addOp(QPainter::CompositionMode_SourceOut, tr("SourceOut"));
    addOp(QPainter::CompositionMode_DestinationOut, tr("DestinationOut"));
    addOp(QPainter::CompositionMode_SourceAtop, tr("SourceAtop"));
    addOp(QPainter::CompositionMode_DestinationAtop, tr("DestinationAtop"));
    addOp(QPainter::CompositionMode_Xor, tr("Xor"));
    addOp(QPainter::CompositionMode_Plus, tr("Plus"));
    addOp(QPainter::CompositionMode_Multiply, tr("Multiply"));
    addOp(QPainter::CompositionMode_Screen, tr("Screen"));
    addOp(QPainter::CompositionMode_Overlay, tr("Overlay"));
    addOp(QPainter::CompositionMode_Darken, tr("Darken"));
    addOp(QPainter::CompositionMode_Lighten, tr("Lighten"));
    addOp(QPainter::CompositionMode_ColorDodge, tr("ColorDodge"));
    addOp(QPainter::CompositionMode_ColorBurn, tr("ColorBurn"));
    addOp(QPainter::CompositionMode_HardLight, tr("HardLight"));
    addOp(QPainter::CompositionMode_SoftLight, tr("SoftLight"));
    addOp(QPainter::CompositionMode_Difference, tr("Difference"));
    addOp(QPainter::CompositionMode_Exclusion, tr("Exclusion"));

Das „ destinationButton “ wird instanziiert und seine Eigenschaft „ iconSize “ wird ebenfalls auf „ resultSize “ gesetzt. Die „ QLabels“ „ equalLabel “ und „ resultLabel “ werden erstellt und die „ minimumWidth “ von „ resultLabel “ wird festgelegt.

    destinationButton = new QToolButton;
    destinationButton->setIconSize(resultSize);

    equalLabel = new QLabel(tr("="));

    resultLabel = new QLabel;
    resultLabel->setMinimumWidth(resultSize.width());

Wir verbinden die folgenden Signale mit den entsprechenden Slots:

  • sourceButtonDas Signal „ clicked()“ von wird mit chooseSource() verbunden,
  • operatorComboBoxdas Signal „ activated()“ von wird mit „ recalculateResult() “ verbunden, und
  • destinationButtondas Signal „ clicked()“ von „“ wird mit „ chooseDestination() “ verbunden.
    connect(sourceButton, &QAbstractButton::clicked,
            this, &ImageComposer::chooseSource);
    connect(operatorComboBox, &QComboBox::activated,
            this, &ImageComposer::recalculateResult);
    connect(destinationButton, &QAbstractButton::clicked,
            this, &ImageComposer::chooseDestination);

Ein ` QGridLayout`, ` mainLayout`, wird verwendet, um alle Widgets zu platzieren. Beachten Sie, dass die Eigenschaft ` sizeConstraint ` von ` mainLayout` auf ` QLayout::SetFixedSize` gesetzt ist, was bedeutet, dass die Größe von ` ImageComposer` überhaupt nicht angepasst werden kann.

    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->addWidget(sourceButton, 0, 0, 3, 1);
    mainLayout->addWidget(operatorComboBox, 1, 1);
    mainLayout->addWidget(destinationButton, 0, 2, 3, 1);
    mainLayout->addWidget(equalLabel, 1, 3);
    mainLayout->addWidget(resultLabel, 0, 4, 3, 1);
    mainLayout->setSizeConstraint(QLayout::SetFixedSize);
    setLayout(mainLayout);

Wir erstellen ein „ QImage “, ein „ resultImage “ und rufen „ loadImage() “ zweimal auf, um beide Bilddateien in unsere „imagecomposition.qrc “-Datei zu laden. Anschließend setzen wir die Eigenschaft „ windowTitle “ auf „Image Composition“.

    resultImage = QImage(resultSize, QImage::Format_ARGB32_Premultiplied);

    loadImage(":/images/butterfly.png", &sourceImage, sourceButton);
    loadImage(":/images/checker.png", &destinationImage, destinationButton);

    setWindowTitle(tr("Image Composition"));
}

Die Funktionen „ chooseSource() “ und „ chooseDestination() “ sind Hilfsfunktionen, die „ chooseImage() “ mit bestimmten Parametern aufrufen.

void ImageComposer::chooseSource()
{
    chooseImage(tr("Choose Source Image"), &sourceImage, sourceButton);
}

void ImageComposer::chooseDestination()
{
    chooseImage(tr("Choose Destination Image"), &destinationImage, destinationButton);
}

Die Funktion „ chooseImage() “ lädt ein Bild nach Wahl des Benutzers, abhängig von den Einstellungen „ title “, „ image “ und „ button “.

void ImageComposer::chooseImage(const QString &title, QImage *image,
                                QToolButton *button)
{
    QString fileName = QFileDialog::getOpenFileName(this, title);
    if (!fileName.isEmpty())
        loadImage(fileName, image, button);
}

Die Funktion „ recalculateResult() “ dient dazu, das Ergebnis der Kombination der beiden Bilder unter Verwendung des vom Benutzer gewählten Kompositionsmodus zu berechnen und anzuzeigen.

void ImageComposer::recalculateResult()
{
    QPainter::CompositionMode mode = currentMode();

    QPainter painter(&resultImage);
    painter.setCompositionMode(QPainter::CompositionMode_Source);
    painter.fillRect(resultImage.rect(), Qt::transparent);
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.drawImage(0, 0, destinationImage);
    painter.setCompositionMode(mode);
    painter.drawImage(0, 0, sourceImage);
    painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);
    painter.fillRect(resultImage.rect(), Qt::white);
    painter.end();

    resultLabel->setPixmap(QPixmap::fromImage(resultImage));
}

Die Funktion „ addOp() “ fügt mithilfe der Funktion „ addItem “ aus „ QComboBox “ ein Element zur „ operatorComboBox “ hinzu. Diese Funktion akzeptiert ein „ QPainter::CompositionMode “, „ mode “ sowie ein „ QString “, „ name “. Das Rechteck wird mit „Qt::Transparent“ gefüllt, und sowohl „ sourceImage “ als auch „ destinationImage “ werden gezeichnet, bevor es auf „ resultLabel “ angezeigt wird.

void ImageComposer::addOp(QPainter::CompositionMode mode, const QString &name)
{
    operatorComboBox->addItem(name, mode);
}

Die Funktion „ loadImage() “ zeichnet mithilfe von „ fillRect()“ einen transparenten Hintergrund und platziert „ image “ mithilfe von „ drawImage()“ mittig. Dieses „ image “ wird anschließend als Symbol für „ button “ festgelegt.

void ImageComposer::loadImage(const QString &fileName, QImage *image,
                              QToolButton *button)
{
    image->load(fileName);

    // Scale the image to given size
    *image = image->scaled(resultSize, Qt::KeepAspectRatio);

    QImage fixedImage(resultSize, QImage::Format_ARGB32_Premultiplied);
    QPainter painter(&fixedImage);
    painter.setCompositionMode(QPainter::CompositionMode_Source);
    painter.fillRect(fixedImage.rect(), Qt::transparent);
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.drawImage(imagePos(*image), *image);
    painter.end();
    button->setIcon(QPixmap::fromImage(fixedImage));

    *image = fixedImage;

    recalculateResult();
}

Die Funktion „ currentMode() “ gibt den aktuell in „ operatorComboBox “ ausgewählten Kompositionsmodus zurück.

QPainter::CompositionMode ImageComposer::currentMode() const
{
    return (QPainter::CompositionMode)
           operatorComboBox->itemData(operatorComboBox->currentIndex()).toInt();
}

Wir verwenden die Funktion „ imagePos() “, um sicherzustellen, dass die in die Objekte „ QToolButton “, „ sourceButton “ und „ destinationButton “ geladenen Bilder zentriert werden.

QPoint ImageComposer::imagePos(const QImage &image) const
{
    return QPoint((resultSize.width() - image.width()) / 2,
                  (resultSize.height() - image.height()) / 2);
}

Die Funktion „ main() “

Die Funktion „ main() “ instanziiert „ QApplication “ und „ ImageComposer “ und ruft deren Funktion „ show()“ auf.

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    ImageComposer composer;
    composer.show();
    return app.exec();
}

Beispielprojekt auf code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.