ImageView

制作一个显示图片的activity,类似相册那样的,可以移动图片,多点触控的时候放大缩小图片等功能

一般就是用BitmapFactory来解码bitmap,然后设置imageView.setImageBitmap()
但是遇到了一个问题,就是图片过大的时候(也没多大,也就是手机摄像头拍的照片,4128x3096,13M像素),真机运行会显示空白,什么都没有
但是模拟器运行正常,就是有一点卡。

在网上搜索的时候看到有一些解释
1,因为图片太大导致的OOM(out of memory)错误
在程序中设置try-catch并没有抓到这个错误,而且debug发现,在BitmapFactory解码图片以后,可以获取到Bitmap的信息,说明也许没有出现这个错误,图片的内存占用仍然在可取范围内

2,需要设置解码的option参数,inSampleSize
这个参数的意思是,把图像的长/宽缩小,再生成Bitmap,inSampleSize的数值是1,2,4这样的比例,然后长/宽就除以这个数值,那么总像素数就除以这个数值的平方

这样的话,内存占用就小了。实际测试的时候,4128X 3096的照片可以显示,内存占用的确小了很多。但是图像放大以后发现果然分辨率也小了。虽然放的不是很大的时候看起来没区别,但是更希望有个解决方案能显示原图的分辨率

而且,快图浏览这个app可以完美显示原分辨率的图像,说明不需要减小分辨率也可以做到正常显示。

3,又发现一个现象,就是长图也无法显示。
比如一个6000X1000的图,总像素6M,内存占用也很小,但是也无法显示。这证明我在第一条里面的推测是正确的,没有出现OOM,解码的时候正常,但是显示的时候错误。

在网上查找发现是这么一个问题,Bitmap too large to be uploaded into a texture
这个信息并不会出现在错误提示里,所以无法catch,只能在logcat里面看到一个warning
但是我用真机测试的时候还没有找到显示Log的方法(网上找到的方法都无效),而模拟器测试又正常,所以没看到这个warning。

Bitmap too large to be uploaded into a texture (5312x2988, max=4096x4096)
有一些网上的信息是这样显示的,说明最大支持的就是4096x4096。
然后我发现,手机里面有一些正好4096像素宽的图像可以正常显示,大一点的比如4128的就不行,我觉得这个解释才是我这个问题的最终解释。

也就是说,是因为图像在显示的时候,有一个最大边长像素数,我的手机的限制是4096,网上也有其他的情况比如2048等等。

解决方案

1 网上提示说可以关闭硬件加速
在manifest文件里面设置 hardwareAcceleration = “false”,就关闭了硬件加速
没错,这样是可以加载长图了,但是APP变卡了,体验非常不好。舍弃

2 用切割法
就说说,每次显示在imageView中的图不是原图的bitmap,通过一个方法
Bitmap.createBitmap(bitmap,x,y,width,height)创建一个bitmap,长宽符合屏幕要求,这样就不会超过像素限制。实际操作以后发现,的确可以显示大图,但是效果也不好,拖动的时候帧数比较低,比上一条的那种好点,但是没有达到最好的要求(就是像快图浏览里面那样的),即便手机自带的相册app也比这个流畅一些。

3,找了半天找到一个github上的项目,运行以后发现完美达到要求
Subsampling Scale Image View
这个解决方案是这样的,其实也是切割法,但是跟上一条不同的是,需要定义一个自定义的VIEW,自己写里面的onDraw方法,绘制bitmap
当然不要一次性画出来,而是根据情况将图切分为能够绘制出来的块。比如现在很多设备的限制是4096X4096,以前貌似是2048x2048,就根据情况切分为最大这样的块,然后绘制每个块,把块拼接起来,就跟原来的图一样了。

变换的时候,在onDraw里面设置matrix canvas.concat(matrix),然后再drawBitmap(...)
这样,每次绘图的时候就会根据matrix来变换了。当然,也可以直接用带matrix参数的drawBitmap。

这就是基本原理。还有一个,就是前面提到的inSampleSize。在不显示大图的情况下,可以设置inSampleSize来缩小图的比例,可以节省内存提高处理速度

补充

实际操作中我发现一个问题,就是设置canvas.concat(matrix)以后,实际变换的是整个canvas的坐标系。

也就是说,变换matrix以后,画布的中心点已经不再是屏幕中心了。这时候如果在原来的坐标画另外一个图形,会发现画在了其他位置,正好和画布的移动吻合,说明是画布移动了,而不是画布上的图像。

所以,设置全局的matrx以后会带来一点问题,就是坐标系也会移动。

找到一个解决办法
不要设置全局的matrix canvas.concat()
改为:

bitmapMatrix.reset();
bitmapMatrix.postTranslate(block.left,block.top);
bitmapMatrix.postConcat(mMatrix);
canvas.drawBitmap(block.bitmap,bitmapMatrix,mPaint);

其中bitmapMatrix是一个单独的matrix
在每次绘图之前,把这个matrix重置,然后添加一个偏移量,就是第二行
再添加全局的matrix,就是第三行。注意第二行和第三行顺序不能反了,实际测试中发现反了以后会显示错误。
这样的话,就不是改变全局坐标,canvas没有变动,变动的是bitmap。

Android 笔记 ImageView 显示大图遇到的问题 以及 无损显示大图 的解决方案相关推荐

  1. android 图片横竖判断_Android应用开发之android 判断ImageView当前显示的是哪一张图片...

    本文将带你了解Android应用开发之android   判断ImageView当前显示的是哪一张图片,希望本文对大家学Android有所帮助. 判断ImageView当前显示的是哪一张图片 Java ...

  2. Android笔记:Dialog显示图片

    下看一下效果图 点击TextView弹出Dialog 点击图片Dialog消失 先看一下MainActivity package com.cxy.demo;import android.app.Act ...

  3. Android在ImageView上直接显示网络图片

    亲测可用,若有疑问请私信 在原生的ImageView中,没有一个方法是可以直接显示网络的图片的,当我们经常需要显示网络图片时,每次都有一大堆的操作,这会很麻烦,今天就教大家在ImageView上轻松显 ...

  4. android imageview 居中显示,Android中ImageView无法居中的问题

    做Android UI布局,尤其是遇到比较复杂的多重LinearLayout嵌套,常常会被一些比较小的问题困扰上半天,比如今天在使用ImageView的时候,想让其居中显示,可是无论怎样设置layou ...

  5. Android使用ImageView显示网络图片

    本案例使用ImageView 简单的实现了网络图片的调用.当中注意事项.由于用到了网络,这里採用了HttpClient方法訪问网络联接,关于怎样使用,可參照文章 Android中使用HttpClien ...

  6. Android 自定义ImageView加载图片

    自定义imageview功能: 可以实现设置图片显示的时候,依据本身的比例进行图片的缩放 加载图片效果: 使用ImageLoader来加载 图片: 首先将ImageLoader的jar包关联到项目中 ...

  7. Android笔记之(图片高斯+Glide实现微信图片加载策略+仿微信进度条)

    很久以前就想自己实现一下仿微信图片加载的那种策略了,先加载一张模糊的图片,然后再加载清晰大图,今天研究了一下,不过要是Glide支持进度条显示就好了,不得不说Glide很强大, 不啰嗦了,直接上代码了 ...

  8. Android笔记:触摸事件的分析与总结----多点触控

       其他相关博文:    Android笔记:触摸事件的分析与总结----MotionEvent对象    Android笔记:触摸事件的分析与总结----TouchEvent处理机制     An ...

  9. 镜像处理坐标 android,Android应用开发之Android重写ImageView实现图片镜像效果的代码教程...

    本文将带你了解Android应用开发之Android重写ImageView实现图片镜像效果的代码教程,希望本文对大家学Android有所帮助. 前两天朋友问我一个问题,如何实现从手机系统相册加载一张图 ...

最新文章

  1. SpringBoot第二十三篇: 异步方法
  2. MySQL数据库介绍、安装(服务端软件安装、客户端软件安装(图形化界面客户端和命令行客户端))
  3. 写在开年:移植wolfssl4.3.0到w60x_sdk_3.04时的一点问题
  4. left join 和 left outer join 的区别【转】
  5. 雷蛇灯光配置文件_雷蛇猎魂光蛛竞技版机械键盘评测
  6. ubuntu linux下建立stm32开发环境: 程序烧录 openocd+openjtag
  7. markdown-Macdown
  8. Struts2中访问HttpServletRequest和HttpSession
  9. Linux 中/etc/profile、~/.bash_profile 环境变量配置以及区别
  10. 一加8系列再次开售 全渠道销售额破亿
  11. HTML 标签学习总结第一天
  12. [LevelDB] 编译和使用
  13. 2020 年的第一天,程序员鸭血粉丝又碰上生产事故
  14. 移动应用设计领域中最拔尖的15大应用
  15. 尚硅谷Docker---docker安装及简介
  16. mysql中转换日期格式,MySQL日期格式转换
  17. 图解HTTP笔记记录
  18. linux usb摄像头驱动程序,Linux系统下USB摄像头驱动开发
  19. IDEA 2018.3.3 有效期至 2100
  20. STM32自学笔记ADC多通道扫描

热门文章

  1. echarts 添加百分号%
  2. RapidMiner 5.3.015源代码下载并且正确的运行
  3. C#—得到服务器时间和国际标准时间
  4. Spark 应用监控告警-Graphite_exporter
  5. verilog练习:hdlbits网站上的做题笔记(5)
  6. 遗传算法_粒子群算法优化支持向量机分类预测-附代码
  7. python绘图黄金螺旋构图_为什么场景插画构图中要用黄金螺旋线?
  8. UML在线绘图 - ProcessOn
  9. 3A和ISP算法概念梳理
  10. 【自学笔记】尚硅谷数据结构与算法Chapter 3 链表