Отрисовка изображений с помощью QPainter

Последнее обновление: 14.01.2024

Для отрисовки изображений Qt предоставляет несколько специальных классов: QImage, QBitmap, QPixmap и QPicture, из которых чаще используется QImage, который позволяет легко загружать, изменять и сохранять изображения.

Для вывода изображения в виде объекта QImage класс QPainter предоставляет метод drawImage(), который имеет ряд версий. Рассмотрим некоторые. В первую очередь, можно определить координаты верхнего левого угла изображения в виде числовых значений или значений QPoint/QPointF:

void drawImage(const QPointF &point, const QImage &image)
void drawImage(const QPoint &point, const QImage &image)
void drawImage(int x, int y, const QImage &image, int sx = 0, int sy = 0, int sw = -1, int sh = -1, Qt::ImageConversionFlags flags = Qt::AutoColor)

Например:

#include <QApplication>
#include <QWidget>
#include <QPainter>

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *)
    {
        QImage image("D:/forest.png");
        QPainter painter(this);
        painter.drawImage(20, 10, image);
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    MyWidget widget;
    widget.setFixedSize(250, 150);
    widget.setWindowTitle("METANIT.COM");

    widget.show();
    return app.exec();
}

В данном случае предполагается, что изображение расположено по абсолютному пути "D:\forest.png". А его верхний левый угол в окне приложения позиционируется на точку с координатами x=20, y=10.

Вывод изображения и метод drawImage в виджетах Qt

Но стоит отметить, что в этом случае изображение выводится в натуральную величину. И в моем случае, к примеру, размеры изображения больше размера окна. И метод drawImage() также имеет версии, которые позволяют масштабировать изображение и вписать его в определенную прямоугольную область, заданную значениями QRectF/QRect

void drawImage(const QRectF &rectangle, const QImage &image)
void drawImage(const QRect &rectangle, const QImage &image)

Применение:

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *)
    {
        QRectF target(20.0, 10.0, 210.0, 130.0);
        QImage image("D:/forest.png");

        QPainter painter(this);
        painter.drawImage(target, image);
    }
};
Вывод и масштабирование изображения и метод drawImage в виджетах Qt

Еще ряд версий позволяет извлечь часть изображения в виде прямоугольной области QRectF/QRect:

void drawImage(const QRectF &target, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags = Qt::AutoColor)
void drawImage(const QRect &target, const QImage &image, const QRect &source, Qt::ImageConversionFlags flags = Qt::AutoColor)

Применение:

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *)
    {

        QRectF target(20.0, 10.0, 210.0, 130.0);
        QRectF source(0.0, 0.0, 250.0, 200.0);
        QImage image("D:/forest.png");

        QPainter painter(this);
        painter.drawImage(target, image, source);
    }
};
Вывод и масштабирование изображения c QPainter и метод drawImage в виджетах Qt

Тажке извлечь часть изображения без масштабирования в натуральную величину:

void drawImage(const QPointF &point, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags = Qt::AutoColor)
void drawImage(const QPoint &point, const QImage &image, const QRect &source, Qt::ImageConversionFlags flags = Qt::AutoColor)

Применение:

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *)
    {
        QRectF target(20.0, 10.0, 210.0, 130.0);
        QRectF source(0.0, 0.0, 250.0, 200.0);
        QImage image("D:/forest.png");

        QPainter painter(this);
        painter.drawImage(QPointF{20.0, 10.0}, image, source);
    }
};
Вывод и обрезка изображения c QPainter и метод drawImage в виджетах Qt

QImage как поверхность изображения

При этом объект QImage может сам выступать в качестве поверхности для рисования, как стандартные виджеты. Например:

#include <QApplication>
#include <QWidget>
#include <QPainter>

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *)
    {
        QImage image(250, 150, QImage::Format_ARGB32);
        QPainter painter1(&image);

        painter1.drawLine(20,20, 230, 130);
        painter1.drawLine(20,130, 230, 20);
        painter1.drawLine(125,20, 125, 130);

        QPainter painter2(this);
        painter2.drawImage(0,0, image);
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    MyWidget widget;
    widget.setFixedSize(250, 150);
    widget.setWindowTitle("METANIT.COM");

    widget.show();
    return app.exec();
}

Здесь применяется два объекта QPainter. Первый в качестве поверхности для рисования будет применять объект QImage:

QImage image(250, 150, QImage::Format_ARGB32);
QPainter painter1(&image);

В конструктор QImage передается ширина и высота изображения. Третий параметр задает цвет - здесь каждый пиксель кодируется 32-битным целым числом — 8 бит для каждого канала: красного, зеленого, синего и значения прозрачности.

Затем первый QPainter рисует на этом изображении три линии

painter1.drawLine(20,20, 230, 130);
painter1.drawLine(20,130, 230, 20);
painter1.drawLine(125,20, 125, 130);

Чтобы отобразить полученное изображение с линиями выводим его в окне приложения с помощью второго объекта QPainter:

QPainter painter2(this);
painter2.drawImage(0,0, image);

Таким образом, один QPainter применяется для рисования на QImage, а другой QPainter - для вывода изображения:

Сохранение изображения QImage из QPainter  в виджетах Qt

Может показаться, что в этом нет смысла, но мы можем использовать функционал QImage для манипуляции с изображением. Например, мы можем сохранить его с помощью метода save()

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *)
    {
        QImage image(250, 150, QImage::Format_ARGB32);
        QPainter painter1(&image);

        painter1.drawLine(20,20, 230, 130);
        painter1.drawLine(20,130, 230, 20);
        painter1.drawLine(125,20, 125, 130);

        image.save("image.png"); // сохраняем изображение

        QPainter painter2(this);
        painter2.drawImage(0,0, image);
    }
};

Здесь QImage сохраняется в файл "image.png" в текущей папке приложения.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850