QPixmap QImage QBitmap QPicture区别

新版qt不支持xp系统,如果需要高版本的qt支持xp系统,需要重新编译源码看

QTreeWidget,QTreeView官方demo实例会卡死,QTreeWidget,QTreeView存在bug和性能上的问题,参考了其他产品的tree widget结构,有些不是用系统自带的tree widget做出来的,需自己自绘制的,所以可以不用qt自带的QTreeWidget,QTreeView做tree widget窗口,可以自己绘制出来。

QPixmap用于图片的显示设计和优化,QPixmap显示更快,但是存储空间不够时,会显示异常

QImage用于图片的显示和单个像素的访问和编辑,比如样色板等功能可以使用

QBitmap用于深度为1的图片比如光标游标,图像比较简单的图片

QPicture用于图像的播放等功能,自定义动画等功能可以使用

二)QImage与QPixmap完全解析

用Qt程序在手机上显示一幅图片对编程人员来说是再基础不过的一件事情了。那么先让大家看两段代码:

//dangerous should not be used, cannot display earth.png,  
//but if we change earth.png to a smaller image e.g. apple.png, apple.png can be displayed
QPixmap pixmap;
pixmap.load( ":/pics/earth.png" );
label->setPixmap( pixmap );


//dangerous should not be used, cannot display earth.png,  
//but if we change earth.png to a smaller image e.g. apple.png, apple.png can be displayed
QPixmap pixmap;
pixmap.load( ":/pics/earth.png" );
QPainter painter(this);
painter.drawPixmap(0,0, pixmap);
大家认为这两段代码有什么问题吗? 看起来好像没什么问题啊。是的,在Windows操作系统上是没有问题的。问题是我们做的是Qt for Symbian! 手机上的资源本来就是比较紧缺的,所以我们使用的时候就需要更加注意。 Qt 为我们提供了四个处理图像的类:QImage,QPixmap,QBitmap 和QPicture。其中前两个是最常使用的。

本文就通过一个例子,一步一步为大家讲解QImage与QPixmap的使用奥秘,在此过程中为大家揭示以上代码存在的缺陷。

QPixmap依赖于硬件

首先需要知道的是QPixmap的具体实现是依赖于系统的。在Symbian系统上QPixmap是被存放在Server端的。 
目前的Qt会把QPixmap都存储在graphics memory中,这明显是依赖硬件的。因此我们对QPixmap的使用需要格外注意。这也正是以上两段代码存在问题的根源。
那么Qt为什么要这么做呢?很简单,设计之初QPixmap就是用来加速显示的,例如我们在paint的时候用QPixmap就会比用其他类的效果好许多。

现在回到我们最初的问题,以上代码到底有什么问题呢?我们可以先用本文提供的例子程序做个试验。当使用上述代码显示较小图片的时候(比如例子程序中的background.png 和apple.png)是没有问题的,图片都能在手机上正确显示。
但是当我们把图片换成一副较大图片287KB,1058 x 1058的“earth.png”的时候就出现问题了,图片无法显示,程序的界面是一片空白。

据测算,“earth.png”被完全解码后存储在graphics memory中会占用大约4.3MB的空间。如果此时还有其他加载的窗口和QPixmap,很可能就没有空间了。

使用QImage加载后转换成QPixmap 显示

那么安全和正确的方法应该是什么呢?答案是我们需要用QImage做一下预处理:

//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);
和QPixmap 不同,QImage是独立于硬件的,它可以同时被另一个线程访问。QImage是存储在客户端的,对QImage的使用是非常方便和安全的。 又由于 QImage 也是一种QPaintDevice,因此我们可以在另一个线程中对其进行绘制,而不需要在GUI 线程中处理,使用这一方式可以很大幅度提高UI响应速度。 因此当图片较大时,我们可以先通过QImage将图片加载进来,然后把图片缩放成需要的尺寸,最后转换成QPixmap 进行显示。

其中需要注意的是Qt::KeepAspectRatio的使用,默认参数是Qt::IgnoreAspectRatio,如果我们在程序中这么写:QPixmap pixmapToShow = QPixmap::fromImage( image.scaled(size(), Qt::IgnoreAspectRatio) );
 

我们也可以直接使用QImage做显示,而不转换成QPixmap ,这要根据我们应用的具体需求来决定,如果需要的话我们可以这么写:

//correct, some times may be needed
QImage image;
image.load( ":/pics/earth.png" );

QPainter painter(this);
painter.drawImage(0,0, image);

 

QPixmap在手机上显示时如果图片过大,会显示不出来的,因为它是依赖于硬件的,存放到

graphics memory(显存,显示内存)的,所以需要将图片放小才能放下,如果需要将大的图片放到手机上显示出来,需要将图片转小,有一下方式实现:

  1. 直接使用小的图片显示即可
  2. 如果一定要使用大的图片,比如有的手机屏幕尺寸不同有的3寸,4寸,到10寸多大的平板电脑等,可以将大的图片转为小的图片即可,如一下方式:

QImage image;
image.load( ":/pics/earth.png" );

QPixmap pixmapToShow = QPixmap::fromImage( image.scaled(size(), Qt::KeepAspectRatio) );

其中的size()很重要,如果设置的值大小有误,超过了屏幕大小导致显存不够会显示不出来,所以size()大小需要适当,如果取得size()还是原先的image的size,大小没有变,还是显示不出来的,因为过大了,size()大小需要小于屏幕大小更安全。

 

 

发布了85 篇原创文章 · 获赞 18 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/a1317338022/article/details/105131372