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

Android 图片处理避免出现oom的方法详解

程序员文章站 2023-12-17 11:28:40
1. 通过设置采样率压缩 res资源图片压缩 decoderesource public bitmap decodesampledbitmapfromres...

1. 通过设置采样率压缩

res资源图片压缩 decoderesource

  public 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);
  }

uri图片压缩 decodestream

  public bitmap decodesampledbitmapfromuri(uri uri, int reqwidth, int reqheight) {
    bitmap bitmap = null;
    try {
    bitmapfactory.options options = new bitmapfactory.options();
    options.injustdecodebounds = true;
    bitmapfactory.decodestream(getcontentresolver().openinputstream(uri), null, options);
    options.insamplesize = bitmaputils.calculateinsamplesize(options,
        utilunitconversion.dip2px(myapplication.mcontext, reqwidth), utilunitconversion.dip2px(myapplication.mcontext, reqheight));
    options.injustdecodebounds = false;

    bitmap = bitmapfactory.decodestream(getcontentresolver().openinputstream(uri), null, options);
    } catch (exception e) {
      e.printstacktrace();
    }
    return bitmap;
  }

本地file url图片压缩

  public static bitmap getloadlbitmap(string load_url, int width, int height) {
    bitmap bitmap = null;
    if (!utiltext.isempty(load_url)) {
      file file = new file(load_url);
      if (file.exists()) {
        fileinputstream fs = null;
        try {
          fs = new fileinputstream(file);
        } catch (filenotfoundexception e) {
          e.printstacktrace();
        }
        if (null != fs) {
          try {
            bitmapfactory.options opts = new bitmapfactory.options();
            opts.injustdecodebounds = true;
            bitmapfactory.decodefiledescriptor(fs.getfd(), null, opts);
            opts.indither = false;
            opts.inpurgeable = true;
            opts.ininputshareable = true;
            opts.intempstorage = new byte[32 * 1024];
            opts.insamplesize = bitmaputils.calculateinsamplesize(opts,
                utilunitconversion.dip2px(myapplication.mcontext, width), utilunitconversion.dip2px(myapplication.mcontext, height));
            opts.injustdecodebounds = false;

            bitmap = bitmapfactory.decodefiledescriptor(fs.getfd(),
                null, opts);
          } catch (ioexception e) {
            e.printstacktrace();
          } finally {
            if (null != fs) {
              try {
                fs.close();
              } catch (ioexception e) {
                e.printstacktrace();
              }
            }
          }
        }
      }
    }
    return bitmap;
  }

根据显示的图片大小进行samplesize的计算

public int calculateinsamplesize(bitmapfactory.options options, int reqwidth, int reqheight) {
    if (reqwidth == 0 || reqheight == 0) {
      return 1;
    }

    // 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;
  }

调用方式:

复制代码 代码如下:

mimageview.setimagebitmap(decodesampledbitmapfromresource(getresources(), r.id.myimage, 100, 100))

bitmap bitmap = decodesampledbitmapfromuri(cropfileuri);
utilbitmap.setimagebitmap(mcontext, mimage,
        utilbitmap.getloadlbitmap(url, 100, 100),
        r.drawable.ic_login_head, true);

2. 质量压缩:指定图片缩小到xkb以下

  // 压缩到100kb以下
  int maxsize = 100 * 1024;
  public static bitmap getbitmapbyte(bitmap oribitmap, int maxsize) {
    bytearrayoutputstream out = new bytearrayoutputstream();
    oribitmap.compress(bitmap.compressformat.jpeg, 100, out);

    byte[] filebytes = out.tobytearray();

    int be = (maxsize * 100) / filebytes.length;

    if (be > 100) {
      be = 100;
    }
    out.reset();
    oribitmap.compress(bitmap.compressformat.jpeg, be, out);
    return oribitmap;
  }

3. 单纯获取图片宽高避免oom的办法

itmapfactory.options这个类,有一个字段叫做 injustdecodebounds 。sdk中对这个成员的说明是这样的:
if set to true, the decoder will return null (no bitmap), but the out...

也就是说,如果我们把它设为true,那么bitmapfactory.decodefile(string path, options opt)并不会真的返回一个bitmap给你,它仅仅会把它的宽,高取回来给你,这样就不会占用太多的内存,也就不会那么频繁的发生oom了。

  /**
   * 根据res获取options,来获取宽高outwidth和options.outheight
   * @param res
   * @param resid
   * @return
   */
  public static bitmapfactory.options decodeoptionsfromresource(resources res, int resid) {
    // first decode with injustdecodebounds=true to check dimensions
    final bitmapfactory.options options = new bitmapfactory.options();
    options.injustdecodebounds = true;
    bitmapfactory.decoderesource(res, resid, options);
    return options;
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: