【QT】QPixmap QImage QBitmap QPicture

文章目录

在Qt中, QPixmapQImageQBitmap 都是用于处理图像数据的类,但它们有不同的特性和适用场景。以下是它们的区别和典型应用场景:


1. QPixmap

特点

  • 设计目的:用于在屏幕上高效显示图像(渲染优化)。
  • 存储方式:依赖于底层图形系统(如X11、DirectFB、OpenGL等)。
  • 像素访问:通常不能直接访问或修改像素(在某些平台上可以,但不推荐)。
  • 线程安全不是线程安全的,只能在主线程(GUI线程)使用。
  • 适用格式:适合显示(如PNG、JPG等),但不适合直接操作像素。

典型应用场景

  • 在UI上显示图片 (如QLabel::setPixmap())。
  • 绘制到QPainter (如QPainter::drawPixmap())。
  • 图标(QIcon)和光标(QCursor)的存储
  • 离屏渲染 (如QPixmap::grabWidget(),但Qt5后推荐用QWidget::grab())。

示例

cpp 复制代码
QPixmap pixmap(":/images/logo.png");
QLabel label;
label.setPixmap(pixmap);

2. QImage

特点

  • 设计目的:用于直接访问和修改像素数据(CPU端操作)。
  • 存储方式:独立于底层图形系统,纯内存存储。
  • 像素访问 :可以直接读写像素(setPixel(), pixel())。
  • 线程安全线程安全,可以在非GUI线程操作(但渲染仍需在主线程)。
  • 适用格式 :支持多种像素格式(Format_RGB32Format_ARGB32等)。

典型应用场景

  • 图像处理(如滤镜、缩放、旋转、格式转换)。
  • 读取/保存图像文件QImage::load(), QImage::save())。
  • 摄像头帧处理 (如QVideoFrameQImage)。
  • OpenCV 和 Qt 结合cv::MatQImage)。

示例

cpp 复制代码
QImage image(":/images/photo.jpg");
image = image.scaled(800, 600, Qt::KeepAspectRatio);
image.setPixel(10, 10, qRgb(255, 0, 0)); // 修改像素
QPixmap pixmap = QPixmap::fromImage(image); // 转QPixmap用于显示

3. QBitmap

特点

  • 设计目的:单色(1-bit)图像,用于掩码(mask)或黑白图像。
  • 继承自 QPixmap,但只支持 Format_MonoFormat_MonoLSB
  • 典型用途
    • 窗口遮罩QWidget::setMask())。
    • 自定义光标(QCursor
    • 黑白图标或图案

示例

cpp 复制代码
QBitmap mask(100, 100);
mask.fill(Qt::color0); // 透明
QPainter painter(&mask);
painter.fillRect(20, 20, 60, 60, Qt::color1); // 不透明部分
widget->setMask(mask); // 设置窗口遮罩

4. 三者的主要区别

特性 QPixmap QImage QBitmap
设计用途 屏幕渲染 像素操作 单色掩码
存储位置 可能存储在GPU 存储在CPU内存 存储在GPU
像素访问 不支持(或受限) 支持(pixel() 不支持
线程安全 仅主线程 线程安全 仅主线程
适用场景 UI显示、绘制 图像处理、修改 遮罩、黑白图像

5. 如何选择?

使用 QPixmap 的情况

  • 需要在 QLabelQPushButton 或其他UI组件上显示图片。
  • 使用 QPainter 进行高效绘制(如游戏、图表渲染)。
  • 需要硬件加速的图形操作。

使用 QImage 的情况

  • 需要直接修改像素(如滤镜、缩放、旋转)。
  • 从摄像头或网络接收图像数据并处理。
  • 需要跨线程处理图像(如后台图像加载)。

使用 QBitmap 的情况

  • 需要创建窗口遮罩(setMask)。
  • 需要黑白图像或自定义光标。

6. 相互转换

  • QImageQPixmap (用于显示):

    cpp 复制代码
    QImage image("photo.jpg");
    QPixmap pixmap = QPixmap::fromImage(image);
  • QPixmapQImage (用于像素操作):

    cpp 复制代码
    QPixmap pixmap("icon.png");
    QImage image = pixmap.toImage();
  • QBitmapQPixmap 的子类 ,可以直接用 QBitmap::fromImage() 转换:

    cpp 复制代码
    QImage monoImage = image.convertToFormat(QImage::Format_Mono);
    QBitmap bitmap = QBitmap::fromImage(monoImage);

7. 性能考虑

  • QPixmap 适合渲染 ,但不能跨线程
  • QImage 适合处理 ,但转换成 QPixmap 有开销
  • 避免频繁转换 ,尽量在 QImage 完成处理后再转 QPixmap

总结

  • QPixmapUI显示(渲染优化)。
  • QImage图像处理(像素操作)。
  • QBitmap单色掩码(遮罩、光标)。

8. QPicture(矢量图形记录与回放)

特点

  • 用于记录和回放 QPainter 命令(如线条、矩形、文本等)。
  • 存储的是绘图指令,而不是像素数据,适合矢量图形。
  • 可以保存到文件(.pic 格式)或从文件加载。

典型应用场景

  • 需要保存和重放绘图操作(如自定义图表、流程图)。
  • 需要缩放无损的图形(因为是矢量格式)。
  • 替代 QPixmap 存储非像素图形。

示例

cpp 复制代码
QPicture picture;
QPainter painter;
painter.begin(&picture); // 记录绘图操作
painter.drawEllipse(10, 10, 100, 100);
painter.end();
picture.save("drawing.pic"); // 保存绘图指令

// 回放
QPicture loadedPic;
loadedPic.load("drawing.pic");
QPainter painter2(this);
painter2.drawPicture(0, 0, loadedPic); // 重新绘制

9. QImageReaderQImageWriter(高效图像读写)

特点

  • QImageReader:优化图像加载(支持渐进式加载、缩放加载)。
  • QImageWriter:优化图像保存(支持压缩、元数据写入)。
  • 比直接使用 QImage::load()/save() 更灵活,支持更多格式控制。

典型应用场景

  • 需要按需加载大图(如仅加载缩略图)。
  • 需要控制图像保存质量(如 JPEG 压缩级别)。
  • 支持动态图像格式(如 GIF、WebP)。

示例

cpp 复制代码
// 渐进式加载图像(适合大图)
QImageReader reader("large_image.jpg");
reader.setScaledSize(QSize(800, 600)); // 直接加载缩小版
QImage image = reader.read();

// 高质量保存 JPEG
QImageWriter writer("output.jpg", "jpg");
writer.setQuality(90); // 设置压缩质量
writer.write(image);

10. QSvgRenderer(SVG 矢量图形渲染)

特点

  • 用于渲染 SVG(Scalable Vector Graphics) 文件。
  • 支持缩放无损显示,适合高分辨率屏幕。
  • 可与 QPainter 结合动态绘制。

典型应用场景

  • 显示矢量图标(如 UI 图标、公司 Logo)。
  • 需要缩放不变形的图形(如地图、流程图)。
  • 替代位图资源,减少内存占用。

示例

cpp 复制代码
QSvgRenderer renderer("icon.svg");
QPainter painter(this);
renderer.render(&painter, QRectF(0, 0, 100, 100)); // 渲染到指定区域

11. QGraphicsPixmapItem(图形视图框架中的图像项)

特点

  • 用于在 QGraphicsScene 中显示 QPixmap
  • 支持平移、旋转、缩放等交互操作。
  • QGraphicsItem 的子类,可与其他图形项组合。

典型应用场景

  • 图形视图框架(如地图、画布)中管理图像。
  • 需要交互式操作的图像(如拖动、旋转)。
  • 游戏开发中的精灵(Sprite)渲染。

示例

cpp 复制代码
QGraphicsScene scene;
QPixmap pixmap("sprite.png");
QGraphicsPixmapItem *item = scene.addPixmap(pixmap);
item->setPos(50, 50);
item->setRotation(45); // 旋转 45 度

QGraphicsView view(&scene);
view.show();

12. QOpenGLTexture(OpenGL 纹理)

特点

  • 将图像绑定为 OpenGL 纹理,用于 3D 渲染。
  • 支持硬件加速的图像处理(如滤镜、着色器)。
  • 需要 Qt 的 OpenGL 模块(QtOpenGL)。

典型应用场景

  • 3D 图形渲染(如游戏、CAD 软件)。
  • GPU 加速的图像处理(如实时滤镜)。
  • QOpenGLWidget 结合使用。

示例

cpp 复制代码
QImage image("texture.png");
QOpenGLTexture texture(image);
texture.bind();
// 在 OpenGL 着色器中使用纹理

13. QVideoFrame(视频帧处理)

特点

  • 用于处理摄像头或视频流的帧数据。
  • 支持与 QImageQPixmap 的转换。
  • 通常与 QMediaPlayerQCamera 结合使用。

典型应用场景

  • 实时视频处理(如人脸检测、AR 应用)。
  • 从摄像头捕获帧并显示。

示例

cpp 复制代码
// 从摄像头获取 QVideoFrame 并转为 QImage
QVideoFrame frame = ...; // 从摄像头捕获
frame.map(QAbstractVideoBuffer::ReadOnly);
QImage image(
    frame.bits(),
    frame.width(),
    frame.height(),
    frame.bytesPerLine(),
    QImage::Format_ARGB32
);
frame.unmap();

// 显示
QPixmap pixmap = QPixmap::fromImage(image);
label.setPixmap(pixmap);

14. QIcon(跨平台图标管理)

特点

  • 封装多种状态的图标(正常、悬停、禁用等)。
  • 支持从 QPixmapQImage 或文件(.ico.png)创建。
  • 自动适配不同设备像素比(High-DPI 屏幕)。

典型应用场景

  • 按钮、菜单项的图标。
  • 适应不同主题(亮色/暗色)的图标切换。

示例

cpp 复制代码
QIcon icon(":/icons/app.png");
QPushButton button;
button.setIcon(icon);

总结:如何选择合适的类?

主要用途 关键优势
QPixmap UI 显示、渲染优化 硬件加速,适合显示
QImage 像素级操作、图像处理 直接访问像素,线程安全
QBitmap 单色掩码、黑白图形 轻量级,适合遮罩
QPicture 矢量图形记录与回放 存储绘图指令,缩放无损
QImageReader 高效图像加载(如渐进式) 支持按需解码
QSvgRenderer SVG 矢量图形渲染 高分辨率适配
QGraphicsPixmapItem 图形视图框架中的交互式图像 支持变换、组合
QOpenGLTexture OpenGL 纹理绑定 GPU 加速渲染
QVideoFrame 视频帧处理 与摄像头/视频流交互
QIcon 跨平台图标管理 支持多状态、High-DPI 适配

根据需求选择最合适的类,可以兼顾性能和功能! 🎨🚀

相关推荐
rigidwill6666 分钟前
华为机试—最大最小路
数据结构·c++·算法·华为od·华为·职场和发展·并查集
春蕾夏荷_72829772512 分钟前
c++ 表格控件 UltimateGrid 控件实例
c++·表格·grid
极客先躯43 分钟前
高级java每日一道面试题-2025年3月31日-微服务篇[Nacos篇]-Nacos集群模式下的部署方案有哪些?
java·开发语言·微服务
go_bai44 分钟前
list的常见接口使用
开发语言·c++·经验分享·笔记·list
积跬步至千里PRO1 小时前
理解JSON-RPC 2.0 协议
qt·rpc·json
鑫—萍1 小时前
数据结构与算法——链表OJ题详解(2)
c语言·开发语言·数据结构·学习·算法·链表
大锦终1 小时前
【C++】继承
c语言·开发语言·数据结构·c++
stevenzqzq1 小时前
kotlin扩展函数
android·开发语言·kotlin
Hello姜先森1 小时前
Kotlin日常使用函数记录
android·开发语言·kotlin
FL16238631291 小时前
[python]通过whl文件安装pyheif安装教程和简单使用案例
开发语言·python