按采样率压缩图片
在使用 BitmapFactory 的解析方法(decodeResource,decodeFile…)创建 Bitmap 的时候,可以传入一个 BitmapFactory.Option 参数,将这个参数的 inJustDecodeBounds 属性设为 true 就可以只返回图片的长宽值和MIME 类型而不会真正的去解析图片,我们就可以根据情况来先对图片进行压缩。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.img, options);
拿到图片的信息后,就可以根据原始图片的大小以及我们需要的图片大小,计算出一个值,设置给 BitmapFactory.Options 的 inSampleSize,通过 inSampleSize 按采样率压缩图片。
int height = options.outHeight;
int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// 计算出实际宽高和目标宽高的比率
int heightRatio = Math.round((float) height / (float) reqHeight);
int widthRatio = Math.round((float) width / (float) reqWidth);
// 选择宽和高中最小的比率作为inSampleSize的值
// 这样可以保证最终图片的宽和高一定都会大于等于目标的宽和高。
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
options.inSampleSize = inSampleSize;
最后把 inJustDecodeBounds 设为 false 并重新解析图片,即可得到压缩后的 Bitmap
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.id.img, options);
使用 LruCache 缓存图片
首先构建 LruCache 对象
// 获取到可用内存的最大值
// 单位 KB
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// 使用最大可用内存值的1/8作为缓存的大小
int cacheSize = maxMemory / 8;
// 创建 LruCache 对象
lruCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// 重写此方法来计算并返回每张图片的大小
// 单位需与传入的 cacheSize 一致,即 KB
return bitmap.getByteCount() / 1024;
}
};
添加图片到 LruCache 中,先判断是否已经缓存,有则不缓存,没有则添加到 LruCache 中
public void addBitmapToLruCache(String key, Bitmap bitmap) {
if (getBitmapFromLruCache(key) == null) {
lruCache.put(key, bitmap);
}
}
从 LruCache 中获取缓存图片
public Bitmap getBitmapFromLruCache(String key) {
return lruCache.get(key);
}