Bitmap加载

来源:互联网 发布:彻底删除苹果手机数据 编辑:程序博客网 时间:2024/05/29 07:33

Bitmap是Android系统中的图像处理的最重要的类之一。通常对于一般小的图片的加载时没有什么问题的,但是如果如果加载比较的大的图片,就很容易发生OOM问题,就是所谓的内存溢出,所以我们就要对图片进行加载管理,就是通过缩放来加载图片。
首先,Bitmap的加载是通过BitmapFactory类提供的一些方法,decodeFile(),decodeResoure(),decodeStream(),decodeByteArray(),decodeFileDescriptor()
其中decodeFile()和decodeResource()最终是调用了decodeStream(),这从源码可以看出:

public static Bitmap decodeFile(String pathName, Options opts) {    Bitmap bm = null;    InputStream stream = null;    try {        stream = new FileInputStream(pathName);        bm = decodeStream(stream, null, opts);    }    ........    return bm;}
public static Bitmap decodeResource(Resources res, int id, Options opts) {.....        bm = decodeResourceStream(res, value, is, null, opts);      .....    return bm;}public static Bitmap decodeResourceStream(Resources res, TypedValue value,        InputStream is, Rect pad, Options opts) {    ........    return decodeStream(is, pad, opts);}

如何加载Bitmap,就是通过缩放。通常,ImageView要显示的图片大小没有那么大,但是如果一开始就整张图片加载进来再进行设置,这就很浪费资源了,我们就可以根据ImageView的宽高需求进行加载。这时候就要通过BitmapFactory.Options来加载大小,这里面还涉及一个采样率inSampleSize。
当inSampleSize为1的时候,图片不进行缩放;当inSampleSize为2的时候,加载的图片均为原来的1/2,整张图片就是原来的1/4大小了,假如原始图片是4M,那么加载进来就只有1M,大大节省空间。

通过采样率加载图片通常有以下四步:

  1. 设置BitmapFactory.Options的inJustDecodeBounds值为true,此时BitmapFactory只会解析图片的原始高度
  2. 根据BitmapFactory.Options获取图片的原始高度和宽度信息
  3. 根据图片的原始高度计算出采样率options.inSampleSize
  4. 设置BitmapFactory.Options的inJustDecodeBounds值为false,此时BitmapFactory会根据采样率加载图片
public Bitmap decodeSampleFromResource(Resources res,int resId,int reqWidth,int reqHeight){    BitmapFactory.Options options = new BitmapFactory.Options();    //此时,BitmapFactory只会解析图片的原始高度和宽度    options.inJustDecodeBounds = true;    BitmapFactory.decodeResource(res,resId,options);    options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);    //此时就会根据inSample来加载    options.inJustDecodeBounds = false;    return BitmapFactory.decodeResource(res,resId,options);}public 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 halfWidth = width / 2;        final int halfHeight = height / 2;        while ((halfWidth / inSampleSize)>=reqWidth && (halfHeight / inSampleSize)>=reqHeight){            inSampleSize *= 2;        }    }    return inSampleSize;}

注意

有些情况下,ImageView宽度和高度是100*100,而原始图片是200*200,当采样率为2的时候,图片就会刚好缩放到100*100。当原始图片是200*300的时候,采样率同为2,图片会缩放到100*150,也是可以的,当采样率为3的时候,就是66*100,那么图片就会被拉伸而变得模糊,为了防止这种情况发生,缩放的时候,必须缩放后的宽度和高度都要大于等于需求的高度,所以:

while ((halfWidth / inSampleSize)>=reqWidth && (halfHeight / inSampleSize)>=reqHeight)
0 0
原创粉丝点击