Bitmap 的压缩与缓存

按采样率压缩图片

在使用 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);  
}

猜你喜欢

转载自blog.csdn.net/dev_fancyluo/article/details/80019367
今日推荐