欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android Bitmap压缩方式分析

程序员文章站 2022-10-29 15:50:32
android bitmap压缩方式分析 在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩);质...

android bitmap压缩方式分析

在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩);质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手机拍照都能达到3m左右了,尺寸压缩一般可用于生成缩略图。

在android开发中我们都会遇到在一个100*100的imageview上显示一张过大的图片,如果直接把这张图片显示上去对我们应用没有一点好处反而存在oom的危险,所以我们有必要采用一种有效压缩方式来显示上去。

private void calculatebitmapinsimplesize() {
    bitmap _bitmap = bitmapfactory.decoderesource(getresources(), r.drawable.bg_homepage);
    getbitmapdatas(_bitmap);

    bitmapfactory.options optioins = new bitmapfactory.options();
    optioins.injustdecodebounds = true;
//    optioins.inpreferredconfig = bitmap.config.rgb_565;//11158560
    optioins.inpreferredconfig = bitmap.config.argb_8888;//22317120
    bitmapfactory.decoderesource(getresources(), r.drawable.bg_homepage, optioins);
    int reqwidth = optioins.outwidth;
    int reqheight = optioins.outheight;

    log.w(tag, "reqwidth = " + reqwidth);
    log.w(tag, "reqheight = " + reqheight);

    int insamplesize = 1;
    final int widthratio = math.round((float)reqwidth / 100f);
    final int heigthratio = math.round((float) reqheight / 100f);
    // 取最小值 这将保证压缩出来的图片大于或者等于请求的宽度或者高度
    insamplesize = widthratio > heigthratio ? heigthratio : widthratio;
    log.w(tag, "first insamplesize = " + insamplesize);

    final int totalpixel = 100 * 100;
    final int totalreqpixel = reqwidth * reqheight * 2;

    log.w(tag, "totalreqpixel = " + totalreqpixel);

    while (totalpixel / (insamplesize * insamplesize) > totalreqpixel) {
      log.w(tag, "totalpixel = " + (totalpixel / (insamplesize * insamplesize)));
      insamplesize ++;
    }

    log.w(tag, "lastinsamplesize = " + insamplesize);

    optioins.injustdecodebounds = false;

    bitmap lastbitmap = bitmapfactory.decoderesource(getresources(), r.drawable.bg_homepage, optioins);
    getbitmapdatas(lastbitmap);

    mimageview.setimagebitmap(lastbitmap);

  }

通过打印log我们可以清楚发现一张原始的图片占有22317120字节,经过压缩后11158560(rgb_565)/ 22317120(rgb8888)明显所占用的内存都减少了,尽量降低这种情况带来的oom。

做法:

1.optioins.injustdecodebounds = true设置为true可用于读取该bitmap的宽高且不会占用内存。

2.optioins.inpreferredconfig = bitmap.config.rgb_565设置在内存中以占用最少的方式,相比rgb_8888只有其一半的内存占有。

3.final int widthratio = math.round((float)reqwidth / 100f);
final int heigthratio = math.round((float) reqheight / 100f);
insamplesize = widthratio > heigthratio ? heigthratio : widthratio;

计算压缩比例,取最小值 这将保证压缩出来的图片大于或者等于请求的宽度或者高度。

4.在要显示到imageview的时候optioins.injustdecodebounds = false设回false这样就能正常显示了

// 计算bitmap所占内存值
 public void getbitmapdatas(bitmap bitmap) {
     log.w(tag, "bitmap size = " + bitmap.getbytecount());
  }

采用以上的压缩方式 我们就能避免一张过大的图片”浪费”的显示在imageview上造成内存消耗过大。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!