Loading Large Bitmaps Efficiently 有效的加载大图片

             在我们开发的过程中有各种各样的图片比如不同的形状的,不同的大小的。在大多的情况下,这些图片不是我们andriod应用程序中所能直接应用的。

比如:系统的Gallery在显示图片的时候,这些图片有的是照相机拍的照片,而这些照片大多都是高分辨率的,而且比手机的分辨率要高的多。

但是我们的手机一般都是内存比较低的,而且在运行应用程序的时候,分配给每个app的内存大小都是有限的,大概16M,而分配给图片的内存有8M,

这个时候你当然是想加载低分辨率的图片到你的内存中,并且这个低分辨率的要能够适配你的ImageView的显示大小。如果加载一个大的图片会让你的内存爆满,当GC来不及回收的时候,会造成你OutMemory的错误。

我们在加载Bitmap的时候通过参数BitmapFactory.Options ,设置inJustDecodeBounds=true,这样在加载的时候不会加载bitmap,返回的是null,但是能把bitmap的宽和高以及outMimeType属性或得到。

Read Bitmap Dimensions and Type (读大图的尺寸和类型)

BitmapFactory是个简单工厂类,提供了我们一些加载的方法  ( decodeByteArray() decodeFile() , decodeResource() , etc.)通过加载不同的资源,来生成Bitmap。如果我们直接用这些方法加载图片的话,那么内存内很快就被分配大量的内存,很快就会导致OutMemory
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
为了避免内存溢出,在加载bitmap之前先查看它的尺寸大小,除非你绝对的知道这个图片真的不会造成内存的溢出。

Load a Scaled Down Version into Memory(加载一个经过缩放的bitmap到内存)

通过我们事先知道这个图片的大小,通过下面的几个因素。我们就可以判断是否要直接加载到内存还是加载一个缩放的图片:
1、加载完整的图像在内存中的估计内存使用情况。
2、你还要给应用程序其他的功能留有一定的内存
3、要加载图片的UI控件的尺寸大小
4、当前设备的屏幕大小和屏幕密度
例如 如果一个imageview,显示像素大小为128*96的,却要加载一个1024*768像素的图片,如果直接加载的话,肯定占用很大的内存,那么我们就要按照128*96的比例来加载。
为了加载一个经过缩放的图片,我们要用到 inSampleSize,在   BitmapFactory.Options中设置
例如:一个图片尺寸是20148*1536却以它的像素的四分之一来加载为512*384的那么占用的内存的大小为0.75MB,而不是原始尺寸12MB。下面有个计算方法:
public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    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;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

应用:
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

显示一个大小为100*100的图片
mImageView.setImageBitmap(
    decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
翻译的不好,各位凑合看吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值