Android图片加载优化
在Android开发中图片加载往往是导致OOM(Out of Memory)的主要原因,所以图片的压缩不得不作为Android开发中比用的一项技能点,以下将以简单的方式进行优化。
图片的大小如何被定义?
其实图片大小的计算是很简单的,只需要用图片的width乘以图片的height然后再乘以每一个像素所占用的字节数,这个字节数需要根据图片解码模式来获得,Android中提供了6种方案,不过常用的只有三个,在下方已经列出。
A:透明度(Alpha)
R:红色(Red)
G:绿(Green)
B:蓝(Blue)
Bitmap.Config.ARGB_8888
:由4个8位组成,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位(4字节)
Bitmap.Config.ARGB_4444
:由4个4位组成,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位 (2字节)
Bitmap.Config.RGB_565
:没有透明度,R=5,G=6,B=5,,那么一个像素点占5+6+5=16位(2字节)
基础知识补脑:
8bit(位)=1byte(字节)
1024byte=1KB
1024kb=1MB
1024mb=1GB
举例:
1、480x800的图片,在色彩模式为ARGB_8888的情况下
480*800*4/1024/1024=1.46484375MB
2、480x800的图片,在色彩模式为ARGB_4444的情况下
480*800*2/1024/1024=0.732421875MB
通过以上的测试,发现导致过大的原因主要集中在两点上,一点是图片的宽和高零一点则是解码方式,通过等比例缩放图片以及切换解码方式可以有效的降低图片的内存占用。不过在以下的优化方案中还有一种优化就是内存复用技术。
优化方案
缩放图片+质量压缩
var bitmapOptions = BitmapFactory.Options()
bitmapOptions.inJustDecodeBounds = true//设置仅加载图片的宽高信息不将图片加载的内存中
BitmapFactory.decodeResource(resources, R.drawable.testimg, bitmapOptions)//获取图片的宽高
bitmapOptions.inSampleSize = 4//设置缩放比例(1、缩放图片)
bitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565//设置解码模式(2、质量压缩)
bitmapOptions.inJustDecodeBounds = false//消除仅加载图片的宽高
var bitmap = BitmapFactory.decodeResource(resources, R.drawable.testimg, bitmapOptions)//加载图片到内存(注意添加Option对象)
this.imgMain.setImageBitmap(bitmap)//使用Bitmap
inSampleSize的作用就是可以把图片的宽高缩小inSampleSize倍,如下代码设置为4那么就是宽高的四分之一,所占内存缩小inSampleSize的平方。单纯的缩放4倍并不充分,只能说治标不治本,好比一个高清50MB的图片,你缩放4倍还是凉凉,所以说还是根据尺寸来计算需要缩放的倍数。
bitmapOptions.inSampleSize =Math.ceil(bitmapOptions.outWidth.toDouble() / targetWidth.toDouble()).toInt()//设置缩放比例(1、缩放图片)
PS:以上的缩放并非精确的缩放
内存复用
何为内存复用,通俗来说就是我已经创建了一个Bitmap对象了,那么我接着还想用一个bitmap对象,那么就可以复用上一个Bitmap对象,不过这样做有两个缺点,第一就是会将之前的图片覆盖掉,第二就是后边加载的图片必须小于或者等于之前的图片大小,否则就不行。
var bitmapOptions1 = BitmapFactory.Options()
bitmapOptions1.inBitmap = bitmap//绑定一个已经加载的Bitmap对象
var bitmap1 = BitmapFactory.decodeResource(resources, R.drawable.timg, bitmapOptions1)//加载新的Bitmap对象
this.imgMain1.setImageBitmap(bitmap1)//使用Bitmap
其他方案
推荐使用WEBP格式代替PNG和JPEG图片格式。
写在最后
以上所说的只是简单的图片压缩优化,并非特定专业的优化方式,不过应对一般的项目需求应该还是可以满足的。