11. Qt深入 QPixmap QBitmap QImage QPicture

参考:https://blog.csdn.net/byxdaz/article/details/146278262

1. 概述

QPainter用于执行绘图操作,QPaintDevice(绘图设备)是二维空间的抽象,可以使用QPainter在其上绘制,QPaintEngine提供了画家在不同类型的设备上绘制的界面。QPaintEngine类由QPainter和QPaintDevice在内部使用,并且对应用程序程序员隐藏,除非他们创建自己的设备类型。

由以上描述可知,QPaintDevice是绘图设备,QPainter可以在QPaintDevice上绘图(即也可以在QPaintDevice的子类上绘图),QPaintEngine是内部使用的,可以不用管。

QPixmap QBitmap QImage QPicture这四个类都是QPaintDevice上的子类,所以可以使用QPainter在这四个类上绘制。

例如下代码是在QPixmap上绘制:

cpp 复制代码
    QPixmap pix(300, 300); //创建一个空的300*300的QPixmap
    pix.fill(Qt::white); //填充颜色
    QPainter painter(&pix); //创建一个在pix上绘制的painter
    painter.setPen(QPen(Qt::green));
    painter.drawEllipse(QPoint(50,50), 50, 50); //zai pix上画圆
    pix.save(/*路径*/); //保存pix

2. 定义

QPixmap :专门为图像在屏幕上的显示做了优化,依赖操作系统绘图引擎,渲染效率高‌。
QBitmap :是 QPixmap 的一个子类,它的色深限定为 1(单色图像)‌。
QImage :专门为图像的像素级访问做了优化,例如可以使用setPixel(int x, int y, uint rgb)设置某个像素点的颜色。
QPicture :记录和重放 QPainter 绘图指令(如绘制路径、图形),存储为二进制绘图指令序列,不直接存储像素数据‌。

注意QPicture,它不像其他三个是存储像素数据的,它是存储绘图指令的,也就是painter执行的操作,例如下面代码:

cpp 复制代码
// 保存QPicture
Widget::Widget(QWidget *parent) : QWidget(parent)
{
    QPicture pic; //QPicture绘图设备,记录和重现绘图指令
    QPainter painter; //创建painter
    painter.begin(&pic); //在QPicture上绘制,实际上picture是将下面这些绘制指令记下来
    painter.setPen(QPen(Qt::green)); //picture记录这条指令
    painter.drawEllipse(QPoint(50,50), 50, 50); //picture记录这条指令
    painter.end(); // 结束绘制
    pic.save("drawing.pic"); //把picture保存为drawing.pic
}

// 重现QPicture命令
void PaintWidget::paintEvent(QPaintEvent *)
{
    QPicture pic;
    pic.load("D:\\drawing.pic"); //从drawing.pic加载picture绘制命令
    QPainter painter;
    painter.drawPicture(200, 200, pic); //将保存的绘图动作重新绘制到设备上
}

3. 区别

4. 适用场景

a) ‌QImage‌

‌图像处理‌:滤镜、缩放、水印等需要直接操作像素的场景‌。

‌跨平台一致性‌:需确保不同操作系统下图像显示完全一致(如生成缩略图)‌。

‌多线程加载‌:在子线程中读取大尺寸图片,避免阻塞主线程‌。

b) ‌QPixmap‌

‌界面显示‌:按钮图标、标签图片等高频渲染需求‌。

‌透明效果‌:支持带 Alpha 通道的 PNG 图片显示‌。

‌硬件加速‌:利用底层绘图引擎提升渲染性能(如动画)‌。

c) ‌QBitmap‌

‌单色图形‌:黑白掩码、光标形状等场景‌。

‌轻量级资源‌:节省内存(如 UI 中的简单图标)‌。

d) ‌QPicture‌

‌绘图指令复用‌:保存复杂绘图操作(如矢量图形),便于重复调用‌。

‌离线渲染‌:将绘图结果序列化为文件,支持后续编辑或传输‌。

5. 注意事项‌

‌颜色深度‌:QBitmap是1位单色位图,转换时需要处理颜色格式(如QImage::convertToFormat(QImage::Format_Mono))。

‌平台依赖‌:QPixmap在不同平台可能有不同底层实现(如X11或DirectFB),建议在主线程操作。

‌性能‌:QPicture存储的是绘图指令,转换为像素图(如QImage/QPixmap)需执行所有绘图命令,可能较慢。

‌线程安全‌:QPixmap和QBitmap不适合在非GUI线程操作,而QImage是线程安全的。

6. 优化建议

相关推荐
我在人间贩卖青春18 小时前
重学Qt——Qt常用界面组件
qt
Larry_Yanan20 小时前
QML面试常见问题(一)QML中组件呈现方式的方法有哪些
开发语言·c++·qt·ui·面试
程序leo源1 天前
Qt信号与槽深度详解
c语言·开发语言·数据库·c++·qt·c#
yu85939581 天前
基于 QT5.7.0 的八线激光雷达点云聚类实现
开发语言·qt·聚类
努力努力再努力wz1 天前
【C++高阶数据结构系列】:时间轮定时器详解:原理分析与代码实现,带你从零手撕时间轮!(附时间轮的实现源码)
c语言·开发语言·数据结构·c++·qt·算法·ui
郝学胜-神的一滴1 天前
Qt 高级开发 006: 架构全解 + 高效学习指南
开发语言·c++·qt·程序人生·架构
会开花的二叉树1 天前
Qt信号槽这套机制
开发语言·qt
小短腿的代码世界1 天前
从KB到字节:Qt行情数据压缩与传输优化的全链路透视——LZ4、Snappy与自定义二进制协议的极限压榨
开发语言·qt
xiaoye-duck1 天前
Qt 入门指南:从Qt历史背景、框架认知到安装和环境搭建
开发语言·qt
hanbr1 天前
Qt:事件处理与绘图详解
开发语言·数据库·qt