Qt 一共提供了四个这样继承 QPaintDevice 的绘图设备类,分别是:QPixmap、QBitmap、QImage和 QPicture。其中:
QPixmap专门为图像在屏幕上的显示做了优化。
QBitmap是 QPixmap 的一个子类,它的色深限定为 1,你可以使用 QPixmap 的 isQBitmap() 函数来确定这个 QPixmap 是不是一个 QBitmap。
QImage专门为图像的像素级访问做了优化。
QPicture则可以记录和重现 QPainter 的各条命令。
特性 | QImage | QPixmap | QBitmap | QPicture |
---|---|---|---|---|
设计目的 | 为像素级操作(读写像素)和 I/O 优化,支持跨平台一致性。 | 为屏幕显示优化,依赖操作系统绘图引擎,渲染效率高。 | 继承自 QPixmap ,色深固定为 1(单色图像)。 |
记录和重放 QPainter 绘图指令(如绘制路径、图形),支持序列化。 |
存储位置 | 客户端内存,独立于硬件,支持多线程操作。 | 图形内存(Windows 下可能存储在客户端内存,其他平台依赖服务端)。 | 与 QPixmap 存储方式相同,但仅支持黑白两色。 |
存储为二进制绘图指令序列,不直接存储像素数据。 |
像素操作 | 支持 setPixel() 和 pixel() 直接修改像素。 |
不支持直接像素操作(需先转换为 QImage )。 |
仅支持单色像素操作(如黑白掩码)。 | 无像素操作功能,通过 QPainter 命令生成图形。 |
线程安全 | 可在非 GUI 线程加载和处理。 | 只能在 GUI 线程使用36。 | 与 QPixmap 相同。 |
支持多线程记录指令,但重放需在 GUI 线程。 |
QImage image("image.png");
QPixmap pixmap = QPixmap::fromImage(image);
需要先将QImage
转为单色(1位深度),再转为QBitmap
:
QImage image("image.png");
QBitmap bitmap = QBitmap::fromImage(image.convertToFormat(QImage::Format_Mono));
需要将QImage
绘制到QPicture
中:
QImage image("image.png");
QPicture picture;
QPainter painter(&picture);
painter.drawImage(0, 0, image);
painter.end(); // 保存到文件 picture.save("image.pic");
QPixmap pixmap("image.png");
QImage image = pixmap.toImage();
如果QPixmap
已经是单色,直接转换:
QPixmap pixmap("bitmap.png");
QBitmap bitmap = QBitmap(pixmap);
否则需要先转为单色格式:
QBitmap bitmap = pixmap.toImage().convertToFormat(QImage::Format_Mono);
将QPixmap
绘制到QPicture
中:
QPixmap pixmap("image.png");
QPicture picture;
QPainter painter(&picture);
painter.drawPixmap(0, 0, pixmap);
painter.end();
QBitmap bitmap("bitmap.bmp");
QImage image = bitmap.toImage();
QBitmap
是QPixmap
的子类,可以直接赋值:
QBitmap bitmap("bitmap.bmp");
QPixmap pixmap = bitmap;
绘制到QPicture
:
QBitmap bitmap("bitmap.bmp");
QPicture picture;
QPainter painter(&picture);
painter.drawPixmap(0, 0, bitmap);
painter.end();
需要将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();
类似上述方法,先绘制到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);
先转为QImage
或QPixmap
,再转为QBitmap
:
// 转为 QImage 再转 QBitmap QImage image = ...; // 如上述方法
QBitmap bitmap = QBitmap::fromImage(image.convertToFormat(QImage::Format_Mono));
QBitmap
是1位单色位图,转换时需要处理颜色格式(如QImage::convertToFormat(QImage::Format_Mono)
)。QPixmap
在不同平台可能有不同底层实现(如X11或DirectFB),建议在主线程操作。QPicture
存储的是绘图指令,转换为像素图(如QImage
/QPixmap
)需执行所有绘图命令,可能较慢。QPixmap
和QBitmap
不适合在非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));
}