Beispiel für die Bildkomposition

Zeigt, wie die Kompositionsmodi in QPainter funktionieren.

Einrichten der Ressourcendatei

Das Beispiel für die Bildkomposition erfordert zwei Quellbilder, butterfly.png und checker.png, die in 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>

Für weitere Informationen über Resource-Dateien siehe Das Qt Resource System.

ImageComposer Klassendefinition

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

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 ImageComposer-Klasse

Wir deklarieren ein QSize Objekt, resultSize, als statische Konstante mit Breite und Höhe gleich 200.

static const QSize resultSize(200, 200);

Im Konstruktor instanziieren wir ein QToolButton Objekt, sourceButton, und setzen seine iconSize Eigenschaft auf resultSize. operatorComboBox wird instanziiert und dann mit Hilfe der addOp() Funktion aufgefüllt. Diese Funktion akzeptiert ein QPainter::CompositionMode, mode, und ein QString, name, das den Namen des Kompositionsmodus darstellt.

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"));

Die Funktion destinationButton wird instanziiert und ihre Eigenschaft iconSize wird ebenfalls auf resultSize gesetzt. Die QLabels equalLabel und resultLabel werden erstellt und die resultLabel's minimumWidth wird gesetzt.

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

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

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

Wir verbinden die folgenden Signale mit ihren entsprechenden Slots:

  • sourceButtonDas Signal clicked() wird mit chooseSource() verbunden,
  • operatorComboBoxDas Signal activated() wird mit recalculateResult() verbunden, und
  • destinationButtonDas Signal clicked() 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 geändert 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, resultImage, und rufen loadImage() zweimal auf, um beide Bilddateien in unsere Datei imagecomposition.qrc zu laden. Dann setzen wir die Eigenschaft windowTitle auf "Bildkomposition".

    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 Komfortfunktionen, 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 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() wird verwendet, um das Ergebnis der Kombination der beiden Bilder zusammen mit dem 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 ein Element zu operatorComboBox hinzu, indem sie die Funktion addItem von QComboBox verwendet. Diese Funktion akzeptiert ein QPainter::CompositionMode, mode, und 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() malt einen transparenten Hintergrund mit fillRect() und zeichnet image an einer zentralen Position mit drawImage(). Dieses image wird dann als das Symbol von 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 Bilder, die auf die Objekte QToolButton, sourceButton und destinationButton geladen werden, zentralisiert sind.

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 @ code.qt.io

© 2025 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.