用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 进行显示。 下图是显示效果(图片是按照earth.png的原始尺寸比例缩放后显示的):

其中需要注意的是Qt::KeepAspectRatio的使用,默认参数是Qt::IgnoreAspectRatio,如果我们在程序中这么写:

QPixmap pixmapToShow = QPixmap::fromImage( image.scaled(size(), Qt::IgnoreAspectRatio) );
效果就是下面这个样子,earth.png被拉伸以充满整个屏幕:

直接使用QImage 显示

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

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

QPainter painter(this);
painter.drawImage(0,0, image);
下面是显示效果(当然我们也可以对其进行缩放之后再显示) 从图片可以看出来它是按照原始尺寸显示earth.png的:

测试设备

本代码已通过在N97和N8上的测试。

======================================
问:piaxmap里加载了一张较大的图片,我想将其缩放小点,长宽与一个label的一致,图片要能全部显示出来,请问怎么做?

答:
Qsize picSize(600,400);
//将pixmap缩放成picSize大小然后保存在scaledPixmap中
按比例缩放:
QPixmap scaledPixmap = pixmap.scaled(picSize, Qt::KeepAspectRatio);
不按照比例缩放
QPixmap scaledPixmap = pixmap.scaled(picSize);
问:
pixmap未定义,还有你写的这几句怎么和label联系起来,菜鸟求指教啊,详细点
答:pixmap就是你说的图像啊 。。。然后用label把scaledPixmap显示出来 就可以了。

注:
QSize 类代表一个矩形区域的大小,实现在 QtCore 共享库中。它可以认为是由一个整型的宽度和整型的高度组合而成的。
QSize(); // 构造一个非法的 QSize 对象
QSize(int width, int height); // 构造宽度为 width、高度为 height 的 QSize 对象

Qt中模型/视图结构:
http://blog.csdn.net/u011314012/article/details/49799623

QAbstractListModel:Qt学习之路(45): 自定义model之一
http://devbean.blog.51cto.com/448512/267435/

QImage与QPixmap完全解析 转:http://blog.csdn.net/jiong_1988/article/details/7472159相关推荐

  1. 数据采集之解析Mysql的binlog日志发送至Kafka实时消费(转:https://blog.csdn.net/liguohuabigdata/article/details/79472777)

    本文采用Maxwell来实现实时解析mysql的binlog日志发送至kafka 1.开启mysql binlog 环境中mysql是docker容器,所以需要进入容器修改mysql配置.docker ...

  2. Android Volley完全解析(二),使用Volley加载网络图片 转载:http://blog.csdn.net/guolin_blog/article/details/174

    转载:http://blog.csdn.net/guolin_blog/article/details/17482165 在上一篇文章中,我们了解了Volley到底是什么,以及它的基本用法.本篇文章中 ...

  3. Android Volley完全解析(一),初识Volley的基本用法 转载地址:http://blog.csdn.net/guolin_blog/article/details/17482095

    转载地址:http://blog.csdn.net/guolin_blog/article/details/17482095 1. Volley简介 我们平时在开发Android应用的时候不可避免地都 ...

  4. 系统权限管理设计 (转:http://blog.csdn.net/chexlong/article/details/37697555)

    权限设计(转:http://blog.csdn.net/chexlong/article/details/37697555)      1. 前言:      权限管理往往是一个极其复杂的问题,但也可 ...

  5. http://blog.csdn.net/LANGXINLEN/article/details/50421988

    GitHub上史上最全的Android开源项目分类汇总 今天在看博客的时候,无意中发现了 @Trinea在GitHub上的一个项目 Android开源项目分类汇总, 由于类容太多了,我没有一个个完整地 ...

  6. http://blog.csdn.net/guolin_blog/article/details/17482095/

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17482095 1. Volley简介 我们平时在开发Android应用的时候不可避 ...

  7. http://blog.csdn.net/neiloid/article/details/7037093#

    1. 显示系统中全部Android平台: android list targets 2. 显示系统中全部AVD(模拟器): android list avd 3. 创建AVD(模拟器): androi ...

  8. GitHub 优秀的 Android 开源项目 转自http://blog.csdn.net/shulianghan/article/details/18046021

    原文地址为http://www.trinea.cn/android/android-open-source-projects-view/,作者Trinea 主要介绍那些不错个性化的View,包括Lis ...

  9. 葵花宝典(转自:https://blog.csdn.net/binbin594738977/article/details/79429301 )

    android开发工具 http://www.androiddevtools.cn/index.html API开发文档(不需要fq) https://developer.android.google ...

最新文章

  1. Centos6.8 搭建Tomcat服务器
  2. isp 图像算法(二)之dead pixel correction坏点矫正
  3. 10的预览模式_谷歌相机2020年3月更新汇总,适配米10等五摄手机,30s手动曝光
  4. 使用Qt设计师文件的3种方式
  5. 中国移动2018年智能硬件质量报告(第一期)——手机芯片评测
  6. P2617 Dynamic Rankings
  7. 语言技巧——scanf读入多行字符串
  8. c语言代码出来在哪里运行,C语言代码,怎么运行。
  9. JavaScript高级程序设计学习笔记(二)
  10. 大数据将走向何方?未来大数据的十大趋势评析
  11. Allegro设置区域规则的方法
  12. 多源异构网络安全关联分析
  13. java小组的队名,霸气小组名称口号大全
  14. java cpu分配_容器中的Java:资源分配准则
  15. centos7安装gparted分区工具及简单操作
  16. 3ds_max入门教程
  17. ucenter php版本,PHP优秀系统UCenter的MVC架构
  18. 项目工作总结2015-2019
  19. Android FM 外部短天线支持(ez fm)
  20. 拉线位移传感器的原理和选型注意事项

热门文章

  1. elasticsearch监控工具之bigdesk
  2. 2021ccpc威海H city safety(最小割,最大权闭合子图)
  3. 2023测试岗面试必问13题(你是在等通知还是拿offer呢?)
  4. jQuery(2) jquery的动画,jquery的ajax,Ajax的全局函数,Jquery的多库共存,Jquery的扩展
  5. 17. STM32——SPI硬件
  6. 河北大学暑假训练营 第一周 平方数
  7. 电商项目1、后端环境搭建
  8. android home跳转,Android 中按home键和跳转到主界面的实例代码
  9. 文件管理:文件存储空间管理
  10. 彩笔的第一个模型:DOTA数据集YOLOv5目标检测