1、压缩图片;
2、LruCache缓存;
一、压缩图片
先介绍下图片质量(Bitmap.Config),一共有4种:
ALPHA_8 只有透明度,没有颜色,那么一个像素点占8位。
RGB_565 即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位。
ARGB_4444 由4个4位组成,即A=4,R=4,G=4,B=4,那么一个像素点占16位。
ARGB_8888 由4个8位组成,即A=8,R=8,G=8,B=8,那么一个像素点占32位。
默认是ARGB_8888。
据此我们可以写出如下函数:
-
- public static int getBytesPerPixel(Bitmap.Config config) {
- if (config == Bitmap.Config.ARGB_8888) {
- return 4;
- } else if (config == Bitmap.Config.RGB_565) {
- return 2;
- } else if (config == Bitmap.Config.ARGB_4444) {
- return 2;
- } else if (config == Bitmap.Config.ALPHA_8) {
- return 1;
- }
- return 1;
- }
-
- public static long getBitmapSizeInMemory(int imageW, int imageH) {
- return imageH * imageW * getBytesPerPixel(Bitmap.Config.ARGB_8888);
- }
BitmapFactory.Options有个inJustDecodeBounds属性,将inJustDecodeBounds设置为true时,就不解码图片到内存,只读取图片的基本信息,读取并设置之后,再把该值改为false,然后再进行解码获取图片,这就是压缩图片的原理。
代码如下:
-
- public static int getScaleInSampleSize(int resW, int resH, int desW, int desH) {
- int scaleW = resW / desW;
- int scaleH = resH / desH;
- int largeScale = scaleH > scaleW ? scaleH : scaleW;
- int sampleSize = 1;
- while (sampleSize < largeScale) {
- sampleSize *= 2;
- }
- return sampleSize;
- }
-
- public static Bitmap decodeBitmapFromResource(Resources res, int resId,
- int reqWidth, int reqHeight) {
-
- final BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeResource(res, resId, options);
- int height = options.outHeight;
- int width = options.outWidth;
- String mimeType = options.outMimeType;
-
- options.inSampleSize = getScaleInSampleSize(width, height, reqWidth, reqHeight);
-
-
- options.inJustDecodeBounds = false;
- return BitmapFactory.decodeResource(res, resId, options);
- }
二、使用LruCache缓存
LruCache缓存主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中,并且把最近最少使用的对象在缓存值即将达到预设定值之前从内存中移除。
用法如下:
- private LruCache<String, Bitmap> mMemoryCache;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
-
-
- int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
-
- int cacheSize = maxMemory / 6;
- mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
- @Override
- protected int sizeOf(String key, Bitmap bitmap) {
-
- return bitmap.getByteCount() / 1024;
- }
- };
- }
- public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
- if (getBitmapFromMemCache(key) == null) {
- mMemoryCache.put(key, bitmap);
- }
- }
- public Bitmap getBitmapFromMemCache(String key) {
- return mMemoryCache.get(key);
- }
- public void loadBitmap(int resId, ImageView imageView) {
- final String imageKey = String.valueOf(resId);
- final Bitmap bitmap = getBitmapFromMemCache(imageKey);
- if (bitmap != null) {
- imageView.setImageBitmap(bitmap);
- } else {
-
- imageView.setImageResource(R.drawable.image_default);
- LoadWorkerTask task = new LoadWorkerTask();
- task.execute(resId);
- }
- }
- class LoadWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
-
- @Override
- protected Bitmap doInBackground(Integer... params) {
- final Bitmap bitmap = decodeBitmapFromResource(
- getResources(), params[0], 100, 100);
- addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
- return bitmap;
- }
- }