安卓开发中,加载图片是一件非常费时费力的事,尤其是对于ListView这种需要加载大量图片并且存活时间短的对象来说,如果不用一些高效加载的方法,对内存的占用是不可估量的,并且很容易出现OOM异常。在对网络图片进行加载时,如果每次都从网络中下载原图资源,不仅花费大量的流量,而且很可能会造成图片加载不及时的现象,影响用户的体验。所以对图片加载的优化是必需的。
最近刚开始接触Android开发,在做一个项目的时候需要做一个商品浏览的功能,就是在ListView的每个Item里面加载多张图片,然后刚开始是在需要用到图片的时候从网上下载资源,这样产生的问题就是每次加载时间会很长,然后每次用都要从网上重新加载,耗费了大量的内存。然后就开始学习图片高速缓存的方法,这里做了一下整理。
方法一 利用BitmapFactory的Options方法压缩图片
无论是从网上下载资源还是本地获取对应文件,都需要用到BitmapFactory.decode函数来转换成Bitmap图片,在decode函数中有一个options属性可以用来更改解码图片的某些参数。
因为如果在原图特别大但是我们所需要用来展示的控件大小并没有那么大的时候,我们就没有必要下载原图。所以我们的思路就是通过按比例缩小原图的分辨率,降低像素数达到优化的目的。同时可以通过降低图片的色彩模式从而降低图片像素点所占内存。
代码
package com.example.h.sdustcamp;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
/**
* Created by Chook_lxk on 18/12/20
*
* @function Bitmap解码压缩
*/
public class BitmapUtil {
/**
* 压缩本地资源文件并获取压缩优化之后的Bitmap对象
* @param filePath
* @param pixelW
* @param piexlH
* @return
*/
public static Bitmap radioFile(String filePath, int pixelW, int piexlH) {
BitmapFactory.Options options = new BitmapFactory.Options();//声明Options对象
options.inJustDecodeBounds = true; //加载的时候只加载图片的宽高属性,不加载原图
options.inPreferredConfig = Bitmap.Config.RGB_565;//降低色彩模式,如果对透明度没有要求,RGB_565即可满足需求
//预加载
BitmapFactory.decodeFile(filePath, options);
//获得原图的宽高属性
int originalW = options.outWidth;
int originalH = options.outHeight;
options.inSampleSize = getSimpleSize(originalW, originalH, pixelW, piexlH);//按照比例确定宽、高,降低分辨率
options.inJustDecodeBounds = false;//取消加载时只加载宽高
return BitmapFactory.decodeFile(filePath, options);//加载图片
}
/**
* 根据原图和目的控件的大小确定压缩比例
* @param originalW
* @param originalH
* @param pixelW
* @param pixelH
* @return
*/
private static int getSimpleSize(int originalW, int originalH, int pixelW, int pixelH) {
int simpleSize = 1;
if(originalW > originalH && originalW > pixelW) { //按照宽度确定比例
simpleSize = originalW / pixelW;
} else if(originalH > originalW && originalH > pixelH) { //按照高度确定比例
simpleSize = originalH / pixelH;
}
if(simpleSize <= 1) { //原图比目的控件小,加载原图
simpleSize = 1;
}
return simpleSize;
}
}
使用方法
Bitmap bitmap = BitmapUtil.radioFile(file.getAbsolutePath(),view.
getWidth(), view.getHeight());