QT编程之图像数据操作(QImage、QPixmap、QBitmap、QPicture)

一、介绍

Qt 一共提供了四个这样继承 QPaintDevice 的绘图设备类,分别是:QPixmap、QBitmap、QImage和 QPicture。其中:
QPixmap专门为图像在屏幕上的显示做了优化。
QBitmap是 QPixmap 的一个子类,它的色深限定为 1,你可以使用 QPixmap 的 isQBitmap() 函数来确定这个 QPixmap 是不是一个 QBitmap。
QImage专门为图像的像素级访问做了优化。
QPicture则可以记录和重现 QPainter 的各条命令。


二、差异对比

特性QImageQPixmapQBitmapQPicture
设计目的为像素级操作(读写像素)和 I/O 优化,支持跨平台一致性‌。为屏幕显示优化,依赖操作系统绘图引擎,渲染效率高‌。继承自 QPixmap,色深固定为 1(单色图像)‌。记录和重放 QPainter 绘图指令(如绘制路径、图形),支持序列化‌。
存储位置客户端内存,独立于硬件,支持多线程操作‌。图形内存(Windows 下可能存储在客户端内存,其他平台依赖服务端)‌。与 QPixmap 存储方式相同,但仅支持黑白两色‌。存储为二进制绘图指令序列,不直接存储像素数据‌。
像素操作支持 setPixel() 和 pixel() 直接修改像素‌。不支持直接像素操作(需先转换为 QImage)‌。仅支持单色像素操作(如黑白掩码)‌。无像素操作功能,通过 QPainter 命令生成图形‌。
线程安全可在非 GUI 线程加载和处理‌。只能在 GUI 线程使用‌36。与 QPixmap 相同‌。支持多线程记录指令,但重放需在 GUI 线程‌。

三、适用场景

1. ‌QImage
  • ‌图像处理‌:滤镜、缩放、水印等需要直接操作像素的场景‌。
  • ‌跨平台一致性‌:需确保不同操作系统下图像显示完全一致(如生成缩略图)‌。
  • ‌多线程加载‌:在子线程中读取大尺寸图片,避免阻塞主线程‌。
2. ‌QPixmap
  • ‌界面显示‌:按钮图标、标签图片等高频渲染需求‌。
  • ‌透明效果‌:支持带 Alpha 通道的 PNG 图片显示‌。
  • ‌硬件加速‌:利用底层绘图引擎提升渲染性能(如动画)‌。
3. ‌QBitmap
  • ‌单色图形‌:黑白掩码、光标形状等场景‌。
  • ‌轻量级资源‌:节省内存(如 UI 中的简单图标)‌。
4. ‌QPicture
  • ‌绘图指令复用‌:保存复杂绘图操作(如矢量图形),便于重复调用‌。
  • ‌离线渲染‌:将绘图结果序列化为文件,支持后续编辑或传输‌。

四、相互转换

1. QImage 与其他类的转换

1.1 QImage → QPixmap
QImage image("image.png"); 
QPixmap pixmap = QPixmap::fromImage(image);
1.2 QImage → QBitmap

需要先将QImage转为单色(1位深度),再转为QBitmap

QImage image("image.png"); 
QBitmap bitmap = QBitmap::fromImage(image.convertToFormat(QImage::Format_Mono));
1.3 QImage → QPicture

需要将QImage绘制到QPicture中:

QImage image("image.png"); 
QPicture picture; 
QPainter painter(&picture); 
painter.drawImage(0, 0, image); 
painter.end(); // 保存到文件 picture.save("image.pic");

2. QPixmap 与其他类的转换

2.1 QPixmap → QImage
QPixmap pixmap("image.png"); 
QImage image = pixmap.toImage();
2.2 QPixmap → QBitmap

如果QPixmap已经是单色,直接转换:

QPixmap pixmap("bitmap.png"); 
QBitmap bitmap = QBitmap(pixmap);

否则需要先转为单色格式:

QBitmap bitmap = pixmap.toImage().convertToFormat(QImage::Format_Mono);
2.3 QPixmap → QPicture

QPixmap绘制到QPicture中:

QPixmap pixmap("image.png");
 QPicture picture; 
QPainter painter(&picture);
 painter.drawPixmap(0, 0, pixmap);
 painter.end();

3. QBitmap 与其他类的转换

3.1 QBitmap → QImage
QBitmap bitmap("bitmap.bmp");
 QImage image = bitmap.toImage();
3.2 QBitmap → QPixmap

QBitmapQPixmap的子类,可以直接赋值:

QBitmap bitmap("bitmap.bmp"); 
QPixmap pixmap = bitmap;
3.3 QBitmap → QPicture

绘制到QPicture

QBitmap bitmap("bitmap.bmp");
 QPicture picture;
 QPainter painter(&picture); 
painter.drawPixmap(0, 0, bitmap);
 painter.end();

4. QPicture 与其他类的转换

4.1 QPicture → QImage

需要将QPicture绘制到QImage上:

QPicture picture; picture.load("image.pic");
 QImage image(800, 600, QImage::Format_ARGB32);
 image.fill(Qt::white); // 设置背景
 QPainter painter(&image); 
painter.drawPicture(0, 0, picture);
painter.end();
4.2 QPicture → QPixmap

类似上述方法,先绘制到QImage,再转QPixmap

QImage image(800, 600, QImage::Format_ARGB32); 
image.fill(Qt::white); 
QPainter painter(&image);
 painter.drawPicture(0, 0, picture); 
painter.end(); 
QPixmap pixmap = QPixmap::fromImage(image);
4.3 QPicture → QBitmap

先转为QImageQPixmap,再转为QBitmap

// 转为 QImage 再转 QBitmap QImage image = ...; // 如上述方法

QBitmap bitmap = QBitmap::fromImage(image.convertToFormat(QImage::Format_Mono));

注意事项

  1. 颜色深度‌:QBitmap是1位单色位图,转换时需要处理颜色格式(如QImage::convertToFormat(QImage::Format_Mono))。
  2. 平台依赖‌:QPixmap在不同平台可能有不同底层实现(如X11或DirectFB),建议在主线程操作。
  3. 性能‌:QPicture存储的是绘图指令,转换为像素图(如QImage/QPixmap)需执行所有绘图命令,可能较慢。
  4. 线程安全‌:QPixmapQBitmap不适合在非GUI线程操作,而QImage是线程安全的。

五、优化建议 

1‌.大图像处理

  • 避免直接加载高分辨率图片到 QPixmap,先用 QImage 缩放:
    QImage image("large.jpg"); 
    image = image.scaled(800, 600, Qt::KeepAspectRatio); // 缩放后转QPixmap
    QPixmap pixmap = QPixmap::fromImage(image);

2.多线程优化

  • 在子线程中用 QImage 加载或处理图像,完成后通过信号传递到主线程转为 QPixmap 显示 。

3.视频显示

QImage 准备好图像数据:

QImage nImage((uchar *)mAVFrameRGB->data[0], mTargetWidth, mTargetHeight, QImage::Format_RGB888);
emit displayImage(nImage); // 发送图片,显示图片

QPixmap 用于绘图显示数据:

void SatVideoWidget::displayImage(QImage nImage){
    nImage = nImage.scaled(640, 480, Qt::KeepAspectRatio);
    mImageLabel->setPixmap(QPixmap::fromImage(nImage));
}
QPixmapQBitmapQt提供的用于处理图像数据的类之一。 QPixmap是为在屏幕上显示图像而设计和优化的类。它可以用于将图像显示在窗口、标签、按钮等控件上。可以通过QLabel的pixmap属性或QPushButton、QToolButton的icon属性来显示QPixmap对象。 QBitmap则是QPixmap的子类,对QPixmap的一些操作进行了封装。不同于QPixmapQBitmap只能存储黑白图像,即只有两种颜色。可以通过使用QBitmap对象来创建只有两种颜色的图标或遮罩。 总结起来,QPixmap是用于显示图像的类,而QBitmapQPixmap的子类,专门用于存储黑白图像。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [QPixmapQImageQPictureQBitmap四者区别](https://blog.csdn.net/luoyayun361/article/details/123366133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Qt提供的四个处理图像的类,Qimagae,QPixmapQBitmapQPicture](https://blog.csdn.net/amu1550/article/details/110124570)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byxdaz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值