Bitmap的高效加载

来源:互联网 发布:人工智能市场前景 编辑:程序博客网 时间:2024/05/16 09:42

如何高效的加载一个Bitmap,这是一个很有意义的话题,因为在我们开发的过程中,经常会遇到这样错误”OutOfMemoryError”这样的错误,很多时候都是因为加载Bitmap出现的内存溢出.

如何加载一个Bitmap

Bitmap在andriod中指的是一张图片,那么如何加载一个图片?BitmapFactory类提供了四类方法:decodeFile,decodeResource,decodeStream和decodeByteFactroy,分别用于支持从文件系统,资源,输入流以及字节数组中加载一个对象,在四类方法最终在andriod的底层实现的,对应着BitmapFactory类的几个native方法.

如何高效的加载一个Bitmap?

其实核心思想很简单,就是使用BitmapFractory,Optins来加载所需尺寸的图片,通过二次采样的方法来缩小图片,从而也减少内存的消耗.
二次采样
1. 将BitmapFactory.Options的inJustDecodeBounds参数设为true
2. 从BitmapFactory.Options来缩放图片,其中它的inSampleSize参数即采样率,当inSampleSize=1的时候,采样率的大小和原图是相同的,当inSampleSize的大小大于1的时候(例如2),采样后的图片宽和高均为原本的1/2,而像素为原来的1/4.
3. 根据采样率的规则并结合目标的View的所需的大小计算出采样率inSampleSize.
4. 讲BitmapFactory.Optinons的inJustDecodeBounds参数设为false,然后重新加载图片

经过上面的几个步骤,加载的图片就是进行缩放后的图片,当然有时候并不需要缩放.在这里说明一下inJustDecodeBounds参数,当此参数设为true的时候,BitmapFactory只会解析图片原始宽/高的问题,而不会真正的去加载图片,因此这个操作是比较轻量级的.

public static Bitmap decodeSampleBitmapFromResource(Resource res,int resId,int reqWidth,int reqHeight){    final BitmapFactory.Options options=new BitmapFactory.Options();    options.inJustDecodeBounds=true;    BitmapFactroy.decodeResoure(res,resId,options);    options.inJustDecodeBounds=false;    return BitmapFactory.decodeResourse(res,resId,options);}public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){    final int height=options.outHeight;    final int width=options.outWidth;    int inSampleSize=1;    if(height>reqHeight||width>reqWidth){    final int halfHeight=height/2;    final int halfWidth=width/2;    while((halfHeight/inSampleSize)>=reqHight &&(halfWidth/inSampleSize)>=reqWidth){    inSampleSize*=2;    }    }    return inSampleSize;}

有了上面的两个方法,使用起来就简单多了,比如ImageView所期望的图片大小为100X100像素的时候,这个时候我们就可以通过如下的方式高效的加载并且显示图片:

mImageView.setImageBitmap(decodeSampledBitmapFromResourse(getResources(),R.id.myimage,100,100));
0 0