关闭

Android 4K高清图片解码显示(3)Bitmap优化

397人阅读 评论(0) 收藏 举报
分类:

上一篇介绍了Android中常用的解码方法。Bitmap是Android开发中经常要使用到的,但是由于Bitmap的使用会占用大量内存,容易造成OOM。Bitmap占用的内存为:像素总数 * 每个像素占用的内存。在Android中,Bitmap有四种像素类型:ARGB_8888、ARGB_4444、ARGB_565、ALPHA_8,他们每个像素占用的字节数分别为4、2、2、1。别看一张图片的大小并不大,但是解码出来之后,一个2000*1000的ARGB_8888类型的Bitmap占用的内存为2000*1000*4=8000000B=8MB,并且每个像素的属性全部保存在内存中!如果是4K高清图片,就会更加庞大。Bitmap优化是Android程序猿必备的技能,常用的优化手段包括:

   1.压缩。通过设置BitmapFactory解码时的属性Options,设置inJustDecodeBounds属性为true,decodeResource()方法就不会生成Bitmap对象,而仅仅是读取该图片的尺寸和类型信息,节约大量内存。       

BitmapFactory.Options options = new BitmapFactory.Options();

options.inJustDecodeBounds = true;

BitmapFactory.decodeResource(getResources(), R.id.test, options);

int imageHeight = options.outHeight;

int imageWidth = options.outWidth;

String imageType = options.outMimeType;

  设置BitmapFactory.Options的inSampleSize属性值,该值表示解析时在长宽两个方向上像素缩小的倍数。inSampleSize的默认值和最小值为1(当小于1时,解码器将该值当做1来处理),且在大于1时,该值只能为2的幂(当不为2的幂时,解码器会取与该值最接近的2的幂)。例如,当inSampleSize为2时,一个2000*1000的图片,将被缩小为1000*500,相应地,它的像素数和内存占用都被缩小为了原来的1/4。下面方法计算可压缩的最大值。  

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) > reqHeight

                && (halfWidth / inSampleSize) > reqWidth) {

            inSampleSize *= 2;

        }

    }

 

    return inSampleSize;

}

也可以直接设置inSampleSize=2进行压缩。最后,获取压缩之后的图片

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,

        int reqWidth, int reqHeight) {

     final BitmapFactory.Options options = new BitmapFactory.Options();

    options.inJustDecodeBounds = true;

    BitmapFactory.decodeResource(res, resId, options);

 

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

    options.inJustDecodeBounds = false;

    return BitmapFactory.decodeResource(res, resId, options);

}

2.使用Cache

3.使用SoftReference

 

   
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1603次
    • 积分:55
    • 等级:
    • 排名:千里之外
    • 原创:4篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档