图片处理涉及的类:
BitMap:
Factory:
BitMapFactory.Option:
BitMap.Config:
图片压缩(大图片加载):
处理思路:
1.获取图片的像素宽高(不加载图片至内存中,所以不会占用资源)
2.计算需要压缩的比例
3.按将图片用计算出的比例压缩,并加载至内存中使用
涉及方法:
/**
* 获取压缩后的图片
* @param res
* @param resId
* @param reqWidth 所需图片压缩尺寸最小宽度
* @param reqHeight 所需图片压缩尺寸最小高度
* @return
*/
public static BitmapdecodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// 首先不加载图片,仅获取图片尺寸
final BitmapFactory.Options options = new BitmapFactory.Options();
// 当inJustDecodeBounds设为true时,不会加载图片仅获取图片尺寸信息
options.inJustDecodeBounds = true;
// 此时仅会将图片信息会保存至options对象内,decode方法不会返回bitmap对象
BitmapFactory.decodeResource(res, resId, options);
// 计算压缩比例,如inSampleSize=4时,图片会压缩成原图的1/4
options.inSampleSize =calculateInSampleSize(options, reqWidth, reqHeight);
// 当inJustDecodeBounds设为false时,BitmapFactory.decode...就会返回图片对象了
options. inJustDecodeBounds = false;
// 利用计算的比例值获取压缩后的图片对象
return BitmapFactory.decodeResource(res, resId, options);
}
/**
* 计算压缩比例值
* @param options 解析图片的配置信息
* @param reqWidth 所需图片压缩尺寸最小宽度
* @param reqHeight 所需图片压缩尺寸最小高度
* @return
*/
public static intcalculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// 保存图片原宽高值
final int height = options. outHeight;
final int width = options. outWidth;
// 初始化压缩比例为1
int inSampleSize = 1;
// 当图片宽高值任何一个大于所需压缩图片宽高值时,进入循环计算系统
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// 压缩比例值每次循环两倍增加,
// 直到原图宽高值的一半除以压缩值后都~大于所需宽高值为止
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
图片加载:
1)图片加载顺序:
内存(强引用,软引用)->文件(sdcard)->网络
2)三级缓存:
内存(强引用+弱引用)+SdCard
重点是内存缓存:
思路:强引用+软引用, 强引用保存常用图片,软应用保存其他图片~
强引用因为不会自动释放对象,所以大小要进行一定限定,否则图片过多会异常, 比如控制里面只存放10张图片或者4M的图片;
然后每次往里面添加图片的时候,检查如果数量超过10张这个阀值,临界点值时,
就移除强引用里面最不常用的那个图片,移除的时候将其保存至软应用缓存池中~
final int MAX_CAPACITY = 10; // 一级缓存阈值
HashMap<String, SoftReference<Bitmap>> mSecondLevelCache = new HashMap<String,SoftReference<Bitmap>>();
// 第一个参数是初始化大小
// 第二个参数0.75是加载因子为经验值
// 第三个参数true则表示按照最近访问量的高低排序,false则表示按照插入顺序排序
HashMap<String, Bitmap>mFirstLevelCache = new LinkedHashMap<String, Bitmap>(
MAX_CAPACITY / 2, 0.75f, true) {
// eldest 最老的对象,即移除的最不常用图片对象
// 返回值 true即移除该对象,false则是不移除
protected booleanremoveEldestEntry(Entry<String, Bitmap> eldest) {
if (size() > MAX_CAPACITY) {// 当缓存池总大小超过阈值的时候,将老的值从一级缓存搬到二级缓存
mSecondLevelCache.put(eldest.getKey(),
new SoftReference<Bitmap>(eldest.getValue()));
return true;
}
return false;
}
};