您的位置:首页 > 移动开发 > Android开发

Android 图片压缩和缓存工具类

2017-01-09 19:06 387 查看
package com.example.xuzuowei.myapplication;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.LruCache;
import android.widget.ImageView;

/**
* 处理图片压缩和缓存的工具类
* Created by admin on 2017/1/9.
*/

public class ImageBitmapFromResourceTool {

/**
* 从资源文件中解析图片得到一个Bitmap对象
*
* @param resources 资源文件目录;
* @param resId     资源文件的Id;
* @param reqWidth  需要设置的宽度;
* @param reqHeight 需要设置的高度;
* @return 返回一个Bitmap对象
*/
public static Bitmap decodeSampledBitmapFromResource(Resources resources, int resId,
int reqWidth, int reqHeight) {
/** 根据BitmapFactory.Options参数的inJustDecodeBounds属性来决定是否要为bitmap分配内存,
*  true 为禁止分配内存,得到的bitmap对象为null,
*  但是BitmapFactory.Options参数中的outWidth,outHeight,outMimeType已经被赋值;
*  false 为可以分配内存,会得到一个bitmap对象;
*/
BitmapFactory.Options opts = new BitmapFactory.Options();
//禁止为bitmap分配内存
opts.inJustDecodeBounds = true;
//调用BitmapFactory的decodeResource方法从资源文件中解析出一个为nulld的bitmap对象,封装源图片的信息;
BitmapFactory.decodeResource(resources, resId, opts);
//调用calculateInSampleSize方法压缩图片,主要是用来设置inSampleSize大小;
//实现图片的压缩就是设置inSampleSize大小;
opts.inSampleSize = calculateInSampleSize(reqWidth, reqHeight, opts);
//为bitmap分配内存空间
opts.inJustDecodeBounds = false;
//返回一个压缩好的bitmap对象
return BitmapFactory.decodeResource(resources, resId, opts);
}

/**
* 通过计算原图片和目标图片宽高的比例,得到一个最小的比率值;
*
* @param reqWidth  目标宽度;
* @param reqHeight 目标高度;
* @param opts      BitmapFactory.Option参数,里面封装源图片的宽高信息;
* @return
*/
public static int calculateInSampleSize(int reqWidth, int reqHeight, BitmapFactory.Options opts) {
//获取源图片的宽高信息
final int outHeight = opts.outHeight;
final int outWidth = opts.outWidth;
int inSampleSize = 1;

//只有实际的图片比期望的图片宽或者高大,就计算压缩比
if (outWidth > reqWidth || outHeight > reqHeight) {
//通过四舍五入得到一个整数比值,实际宽高除以期望宽高
final int width = Math.round(outWidth / reqWidth);
final int height = Math.round(outHeight / reqHeight);
// 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
// 一定都会大于等于目标的宽和高。
inSampleSize = width > height ? height : width;
}
return inSampleSize;
}

/**
* 从内存中读取图片缓存,设置个imageview,如果内存中没有就从资源文件中读取,并压缩处理,在添加到缓存中;
*
* @param resId
* @param imageView
*/
public static void loadBitmapFromMemoryCache(Resources resources, int resId, ImageView imageView,int
d719
reqWidth,int reqHeight) {
String bitmapKey = String.valueOf(resId);
final Bitmap memoryInBitmap = getMemoryInBitmap(getLruCacheMemory(), bitmapKey);

if (memoryInBitmap != null)
imageView.setImageBitmap(memoryInBitmap);
else {
imageView.setImageResource(R.mipmap.ic_launcher);  //先显示一个默认图片
new BitmapWorkerTask(resources, imageView,
reqWidth, reqHeight).execute(resId);
}

}

/**
* 开启后台异步线程,来加载和缓存图片
*/
static class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private Resources mResources;
private ImageView mImageView;
private int outWidth;
private int outHeight;

public BitmapWorkerTask(Resources resources, ImageView imageView, int reqWidth, int reqHeight) {
mResources = resources;
mImageView = imageView;
outWidth = reqWidth;
outHeight = reqHeight;
}

@Override
protected Bitmap doInBackground(Integer... params) {
//从资源文件中解析并压缩图片,添加到缓存中.
final Bitmap bitmap = decodeSampledBitmapFromResource(mResources, params[0], outWidth, outHeight);
addBitmapToMemoryCache(getLruCacheMemory(), String.valueOf(params[0]), bitmap);
return bitmap;
}

@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
//设置显示图片;
mImageView.setImageBitmap(bitmap);
}
}

/**
* 获取LruCache缓存空间
* <p>
* cacheMemory是设置LruCache缓存空间的大小为可用空间总大小的1/8 kb;
*
* @return
*/
public static LruCache getLruCacheMemory() {
//获取可用内存的最大值.单位kb;
final int maxMemory = (int) Runtime.getRuntime().maxMemory() / 1024;
//假如使用1/8内存作为缓存空间;
int cacheMemory = maxMemory / 8;
final LruCache<String, Bitmap> lruCache = new LruCache<String, Bitmap>(cacheMemory) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
//重写方法返回每一个bitmap对象的大小,默认返回bitmap数量;
return bitmap.getByteCount() / 1024;
}
};

return lruCache;
}

/**
* 添加bitmap到缓存中
*
* @param lruCache
* @param key
* @param bitmap
*/
public static void addBitmapToMemoryCache(LruCache<String, Bitmap> lruCache, String key, Bitmap bitmap) {
if (lruCache.get(key) == null)
lruCache.put(key, bitmap);
}

/**
* 获取缓存图片bitmap;
*
* @param lruCache LruCache缓存对象
* @param key      bitmap唯一键
*/
public static Bitmap getMemoryInBitmap(LruCache<String, Bitmap> lruCache, String key) {
return lruCache.get(key);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: