QPixmap、QBitmap、QImage 与 QPicture

Qt在图像方面提供了QPixmap、QBitmap、QImage、QPicture这些类,他们在使用时存在着一些区别,需要引起注意。

一. 几种类的简介

QPixmap继承了QPaintDevice,可用以建立QPainter并在它之上进行绘图,也可以直接指定图像载入Qt所支持的格式,如BMP、GIF、JPG、JPEG、PNG等,并使用QPainter的drawPixmap()绘制在其它的绘图装置上。可以在QLabel、QPushButton上设定QPixmap以显示图像QPixmap是针对屏幕显示图像而设定并最佳化,依赖于所在平台的绘图引擎,所以一些效果的显示(如反锯齿),在不同的平台上显示效果可能会有差异。

QBitmap是QPixmap的子类,提供单色图像,可用于制作光标(QCursor)或画刷(QBrush)。下面的程序载入相同的图像,用来观察QPixmap和QBitmap的显示效果。下面的程序载入相同的图像,以观察QPixmap与QBitmap的显示效果。

#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QBitmap>

class PainterWidget : public QWidget {
protected:
    void paintEvent(QPaintEvent*);
};

void PainterWidget::paintEvent(QPaintEvent *event) {
    QPixmap pixImg("caterpillar.jpg");
    QBitmap bitImg("caterpillar.jpg");
    QPainter painter(this);
    painter.drawPixmap(0, 0, pixImg);
    painter.drawPixmap(200, 0, bitImg);
}

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    
    PainterWidget pWidget;
    pWidget.setWindowTitle("QPixmap & QBitmap");
    pWidget.resize(400, 150);
    pWidget.show();
    
    return app.exec();
}
显示效果如下:



QPixmap使用平台的绘图引擎,在不同的平台所呈現的效果不一,无法提供个別像素的存取,QImage使用Qt自身的绘图引擎,可提供在不同平台上相同的图像呈现效果,并可透过setPixpel()、pixel()等方法,直接存取指定的像素,例如在Qt的QImage文件中,就有提供以下的示例:(其中像素坐标的索引,和传统的OpenCV是不一样的)。

QImage image(3, 3, QImage::Format_RGB32);
 QRgb value;

 value = qRgb(189, 149, 39); // 0xffbd9527
 image.setPixel(1, 1, value);

 value = qRgb(122, 163, 39); // 0xff7aa327
 image.setPixel(0, 1, value);
 image.setPixel(1, 0, value);

 value = qRgb(237, 187, 51); // 0xffedba31
 image.setPixel(2, 1, value);
显示效果如下:



QPicture则是个绘图装置,可以记录并重播QPainter的绘图指令,可以使用QPainter的begin()方 法,指定在QPicture上进行绘图,使用end()方法结束绘图,使用QPicture的save()方法將QPainter所使用过的绘图指令存至文件,例如:
QPicture picture;
QPainter painter;
painter.begin(&picture); 
painter.drawRect(10, 20, 100, 50);
painter.end();
picture.save("draw_record.pic");

要重播绘图指令的話,建立一個QPicture,使用load()方法载入绘图指令的文件,然后在指定的绘图裝置上绘制QPicture:
QPicture picture;
picture.load("draw_record.pic");  
QPainter painter;
painter.begin(this);
painter.drawPicture(0, 0, picture); 
painter.end(); 


    
二. QPixmap和QImage的区别
1. QPixmap是专门为绘图而生,当需要绘制图片时需要使用QPixmap。

    QImage则是I/O,为图片像素访问以及修改而设计的。如果你想访问图片的像素或是修改图片像素,则需要使用QImage,或者借助于QPainter来操作像素。
    另外跟QImage不同是,QPixmap跟硬件是相关的,如X11, Mac 以及 Symbian平台上,QPixmap 是存储在服务器端,而QImage则是存储在客户端。

    在Windows平台上,QPixmap和QImage都是存储在客户端,并不使用任何的GDI资源。


2. 速度上,在X11, Mac 以及 Symbian平台上,QImage: 因为它是存储在客户端,QImage上绘图比较快,但显示它则比较慢。

    QPixmap: 因为它是存储在服务器端,往QPixmap上绘图比较慢,但显示它则比较快。

    但在Windows平台上则是是一样的,因为它们都存储在客户端。

三. QImage与QPixmap完全解析

    3.1 先看两段代码:

    代码1

QPixmap pixmap;
pixmap.load( ":/pics/earth.png" );
label->setPixmap( pixmap );

    代码2

QPixmap pixmap;
pixmap.load( ":/pics/earth.png" );
QPainter painter(this);
painter.drawPixmap(0,0, pixmap);
看起来好像没什么问题啊。是的,在Windows操作系统上是没有问题的。问题是我们做的是Qt for Symbian! 手机上的资源本来就是比较紧缺的,所以我们使用的时候就需要更加注意。 
Qt 为我们提供了四个处理图像的类:QImage,QPixmap,QBitmap 和QPicture。其中前两个是最常使用的。


3.2 QPixmap依赖于硬件
        设计之初QPixmap就是用来加速显示的,例如我们在paint的时候用QPixmap就会比用其他类的效果好许多。当使用上述代码显示较小图片的时候(比如例子程序中的background.png 和apple.png)是没有问题的,图片都能在手机上正确显示。
但是当我们把图片换成一副较大图片287KB,1058 x 1058的“earth.png”的时候就出现问题了,图片无法显示,程序的界面是一片空白。据测算,“earth.png”被完全解码后存储在graphics memory中会占用大约4.3MB的空间。如果此时还有其他加载的窗口和QPixmap,很可能就没有空间了。
3.3 正确的方法
       正确的方法应该先用QImage获取图像,并且做一下预处理,然后再用QPixmap来加速显示。和QPixmap 不同,QImage是独立于硬件的,它可以同时被另一个线程访问。QImage是存储在客户端的,对QImage的使用是非常方便和安全的。 又由于 QImage 也是一种QPaintDevice,因此我们可以在另一个线程中对其进行绘制,而不需要在GUI 线程中处理,使用这一方式可以很大幅度提高UI响应速度。 因此当图片较大时,我们可以先通过QImage将图片加载进来,然后把图片缩放成需要的尺寸,最后转换成QPixmap 进行显示。正确的代码如下:

//correct and recommended way
QImage image;
image.load( ":/pics/earth.png" );

QPainter painter(this);
QPixmap pixmapToShow = QPixmap::fromImage( image.scaled(size(), Qt::KeepAspectRatio) );
painter.drawPixmap(0,0, pixmapToShow);

显示效果如下:

EarthKeepAspectRatio.JPG    EarthIgnoreAspectRatio.JPG    EarthDislayByImage.JPG

第一图是显示效果(图片是按照earth.png的原始尺寸比例缩放后显示的),第二图的代码为:QPixmap pixmapToShow = QPixmap::fromImage( image.scaled(size(), Qt::IgnoreAspectRatio) ); 

下面便是第三图的实现代码,可以显示,一方面比较的慢,另外一方面只能显示部分。
//correct, some times may be needed
QImage image;
image.load( ":/pics/earth.png" );
QPainter painter(this);
painter.drawImage(0,0, image);


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QPixmap和QBitmapQt提供的用于处理图像数据的类之一。 QPixmap是为在屏幕上显示图像而设计和优化的类。它可以用于将图像显示在窗口、标签、按钮等控件上。可以通过QLabel的pixmap属性或QPushButton、QToolButton的icon属性来显示QPixmap对象。 QBitmap则是QPixmap的子类,对QPixmap的一些操作进行了封装。不同于QPixmap,QBitmap只能存储黑白图像,即只有两种颜色。可以通过使用QBitmap对象来创建只有两种颜色的图标或遮罩。 总结起来,QPixmap是用于显示图像的类,而QBitmapQPixmap的子类,专门用于存储黑白图像。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [QPixmap、QImage、QPicture、QBitmap四者区别](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,QPixmap,QBitmap,QPicture](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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值