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:
sourceButton
Das Signal clicked() wird mitchooseSource()
verbunden,operatorComboBox
Das Signal activated() wird mitrecalculateResult()
verbunden, unddestinationButton
Das Signal clicked() wird mitchooseDestination()
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(); }
© 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.