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

Bitmap高效加载图片

2016-07-09 18:28 225 查看
  一、什么是Bitmap
   Bitmap在Android中指一张图,格式不定。BitmapFactory提供了四类方法:decodeFile.decodeResource
 decodeStream和decodeByteArray,分别支持从文件,资源,输入流以及字节数组加载出一个bitmap对象,
 其中decodeFile和decodeResource间接调用了decodeStream。
   二、高效加载的核心原理
     怎么高效地加载Bitmap,可以说之加载所需尺寸就行了,一般来说原始图片都比显示出来的图片要大,
 越大的图片加速度、效率就会越低,那么我们在加载之前对图片进行缩放处理,这样使得效率提高,而且
 可以在一定程度上避免OOM我们通过BitmapFactory.Options来缩放图片,主要是其中的inSampleSize参数,
 即采样率。当inSampleSize为1时,采样后的图片大小为原始大小;当inSampleSize为2时,那么采样后的宽
 高均为原图的1/2,而像素数为原图的1/4,内存占用也为原图的1/4,在Goole官方文档中还指出
 inSampleSize的取值应该总为2的指数,比如:1,2,4,8...如果不为2的指数那么系统会自动向下取整并选择
 一个最接近2的指数来代替。
   三、实际开发中的意外情况
    另外考虑以下实际情况,假设我们用ImageView来显示图片,当ImageView的大小为100x100像素,而图片
 原始大小为200x200,那么只需将采样率inSampleSize设置为2即可,但是如果图片大小为200x300呢?如果采
 样率选择2,那么缩放后片大小为100x150,也可以继续用ImageView,如果采样率为3,那么缩放后图片大小
 就会小于ImageView,所期望的大小,那么图片会被自动拉伸而导致模糊
    (ImageView底层代码原理,当加载的资源与本身大小不一样时,会自动调用requestLayout(),然后调用
  父节点的requestLayout()重新布局,在此过程中会自动对资源进行缩放拉伸处理)
  四、过程
    获取采样率
    1.将BitmapFactory.Options的inJustDecodeBounds参数设置为false,并加载图片(为了测量图片宽高)
    2.从BitmapFactory.Options中取出图片的原始宽高信息(存放在options参数中)
    3.根据采样率的规则并结合目标View的所需大小计算出采样率inSampleSize。
    4.将BitmapFactory.Options的inJustDecodeBounds参数设置为false,并重新加载图片
	注释:当inJustDecodeBounds为true时,只会解析图片的宽高信息,而不去加载图片
    代码如下:
public class MainActivity extends AppCompatActivity {

private ImageView im_1;
private ImageView im_2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
im_1 = (ImageView) findViewById(R.id.im_1);
im_2= (ImageView) findViewById(R.id.im_2);

im_1.setBackgroundResource(R.drawable.tiantang);
im_2.setImageBitmap(decodeSampledBitmapFromResources(getResources(),R.drawable.tiantang,100,100));

}

private Bitmap decodeSampledBitmapFromResources(Resources res,int resId,int reqWidth,int reqHeight){
//1.找到BitmapFactory实例
BitmapFactory.Options options = new BitmapFactory.Options();
//2.设置inJustDecodeBounds参数为True
options.inJustDecodeBounds = true;
//3.得到BitmapFactory加载进来的图片
BitmapFactory.decodeResource(res, resId, options);

//4.计算缩放比
options.inSampleSize =calculateInSampleSize(options,reqWidth,reqHeight);

options.inJustDecodeBounds =false;
return BitmapFactory.decodeResource(res,resId,options);
}

private int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){
int height = options.outHeight;
int width = options.outWidth;

int inSampleSize =1;
//当图片宽高其中一个大于要求宽高
if(height>reqHeight||width >reqWidth){
int halfHeight = height/2;
int halfWidth = width/2;
//循环直到得到合适的采样率
while((halfHeight/inSampleSize)>=reqHeight && (halfWidth/inSampleSize)>=reqWidth){
inSampleSize *=2;
}
}
return inSampleSize;
}
}

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