您的位置:首页 > 移动开发 > Android开发

android之图片压缩

2016-03-19 20:38 405 查看
移动开发中,对图片的处理并不像web那样简单(web中只需要一张图片的url就可以显示在网页中),在app中,如果加载一个大图片,很有可能会出现OOM的问题,其根本原因在于,当加载大图片时,图片所占用的内存空间极有可能超过了当前app剩余的内存容量,甚至是超过了app最大的内存空间。 有人可能会问,我加载的图片明明只有2~3M而已,而且现在手机的内存容量都这么大,怎么会超出呢?那下面来说说我的理解(当然有参考过大牛的文章,大神们不要拍砖哈)

一、如何得知一个app的最大内存空间

首先要解除的一个疑惑是:手机的内存容量并不代表app的最大内存空间,系统对每个app都有它默认的内存占用空间,当然也可以调节。那么如何知道app的最大内存空间呢,可以用下面两个简单的方法:

1、使用代码

Runtime.getRuntime().maxMemory();


2、使用adb命令

adb shell dumpsys meminfo $package_name or $pid  //使用程序的包名或进程id




从上图可知,这个app的的内存大小是24M左右(我用的手机是nexus5,不同的手机这个值会不一样)

二、如何预计一张大图片可能要占用的内存大小

当然,并非所有的图片我们都需要进行压缩,比如放在drawable文件夹里面的icon图片大多不用压缩,直接使用就行了,但对于网络图片,个人建议还是先进行判断是否需要压缩,可以用下面的方法对图片占用的内存空间进行一个预估:

图片内存占用估值=bitmap.getWidth() * bitmap.getHeight() *  每个px占用的byte数;
其中,每个px占用的byte数与inPreferredConfig参数有关
参考如下:点击打开链接

1、ARGB_8888:分别用8位来记录4个值,即每个px占用8*4/8=4个bytes;
2、RGB_4444:分别用4个来记录4个值,即每个px占用4*4/8=2个bytes;
3、RGB_565:分别用5位,6位,5位还记录RGB3个值,即每个px占用(5+6+5)/8=2个bytes;
4、ALPHA_8:不保存颜色值,只用8位记录透明度,即每个px占用8/8=1个byte;
推荐使用ARGB_8888和RGB_565,其中ARGB_8888为默认方式;

如:nexus5手机拍出的照片大小2.80M,height=3264,width=2448,则以ARGB_8888来加载这张图片,会占用的手机内存是:3264 * 2448 * 8 个byte,相当于30M;而默认情况下,nexus5中app的最大内存是24M,此时,如果不进行压缩,则一定会出现OOM。

三、常用的压缩方法:采样及质量压缩
1、采样压缩如下:







2、质量压缩如下:



区别如下:
采样压缩法可以使图片占用的内存大大减小,但不足之处在于,其采用的sampleSize是2的乘方的倍数;
质量压缩法只能压缩图片文件的大小,并不能减小图片占用内存的大小,因为要保证像素不变,其次,质量压缩也不能无限减小图片文件的大小,最终会减小到一个固定的值;

四、实际使用

在实际项目中,如果要加载一张大图片,且要求压缩后的图片在100K内,解决方式如下:
1、采样压缩
2、质量压缩
3、判断图片与ImageView的边界



4、对压缩过的图片进行保存(可无)



这个东西很早就写了,一直没有发出来,所以代码部分都是图片的形式(以前整理到云笔记里了,代码都是图片的),这里面也参考了些其他地方的讲解,会在下面贴出来,如果有哪里不对的,请大神们指正,谢谢各位了

参考如下:

1、http://104zz.iteye.com/blog/1694762
2、http://www.tuicool.com/articles/vEf6Nf
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: