1、QPixmap和QImage区别
QImage 是给 CPU 用的(用于处理数据),QPixmap 是给 GPU/屏幕用的(用于显示)
| 特性 | QImage | QPixmap |
|---|---|---|
| 存储位置 | 系统内存 (CPU) | 图形硬件/显存 (GPU) |
| 主要用途 | 图像处理 (修改像素、算法分析) | 屏幕显示 (绘图、界面展示) |
| 访问方式 | 可以直接访问和修改像素数据 | 只能通过 QPainter 绘制,不能直接改像素 |
| 绘制性能 | 较慢 (需要把数据从内存传给显卡) | 极快 (数据已在显存,直接渲染) |
| 线程安全 | 是 (可以在子线程处理图像) | 否 (通常只能在主线程/GUI线程使用) |
QImage:像"原始数据"
-
作用:它就像一块内存画布,你可以随时读写上面的每一个像素点。
-
场景:
-
从摄像头或文件读取图片。
-
做图像处理(如:把图片变灰、边缘检测、人脸识别)。
-
你需要直接操作像素值
-
-
缺点 :如果你试图把
QImage直接画到屏幕上,Qt 需要把数据从内存拷贝到显卡,这在频繁刷新(如你的工业仪表盘)时会非常消耗性能。
QPixmap:像"显卡纹理"
-
作用 :它是专门为屏幕显示优化的。它把图像数据存储在显存中(或者图形系统的后端存储中)。
-
场景:
-
在
paintEvent中绘制背景、图标、曲线。 -
作为双缓冲的"画布"(即你刚才问的 Demo 中的
m_pixmap)。
-
-
优点:绘制速度极快,因为 GPU 可以直接拿来用,不需要数据搬运。
-
缺点 :你不能直接去改它的像素(比如不能写
pixmap.setPixel),必须先转成QImage改了再转回来,或者用QPainter去画它。
经典工作流:QImage 转 QPixmap
在刚才的工业仪表盘场景中,最标准的流程通常是这样的:
- 采集/处理 (QImage) :
- 后台线程从硬件读取数据,或者加载一张复杂的背景图。
- 使用
QImage进行缩放、格式转换(比如转成Format_RGB32)。
- 转换 (Convert) :
- 调用
QPixmap::fromImage(myImage)将处理好的数据上传到显存。
- 调用
- 显示 (QPixmap) :
- 在
paintEvent中,使用QPainter::drawPixmap(...)将显存中的图像快速"贴"到屏幕上。
- 在
总结
- 如果你要算 图(改颜色、读数据),用 QImage。
- 如果你要画 图(显示界面、双缓冲),用 QPixmap
2、嵌入式设备如何优化绘图性能
什么是双缓冲?
-
普通绘制(单缓冲):直接在屏幕上画。先画背景(白),再画曲线(红)。人眼会看到"白屏一闪 -> 红线出现",这就是闪烁。而且在 ARM 上,绘图操作慢,屏幕会逐步显示绘制过程。
-
双缓冲 :先在内存里(一张看不见的图片)把所有东西画好,画完后,一次性把这张图片"贴"到屏幕上。人眼只看到最终结果,没有中间过程,因此 无闪烁 且 视觉更流畅
如果你在实际项目中遇到性能瓶颈,还可以结合以下策略:
- 局部刷新 :如果只有指针在动,背景不动,可以只重绘指针区域(
update(rect)),而不是整个窗口。 - 静态/动态分离 :将背景(刻度盘)画在一个静态的
QPixmap里缓存起来,每次只把背景图和动态指针图叠加(类似图层概念),减少重复计算刻度。 - 使用 OpenGL/Vulkan :对于极度复杂的波形或 3D 仪表,Qt Widgets 的 CPU 软绘可能扛不住,这时需要用到
QOpenGLWidget,利用 GPU 硬件加速