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