图片质量压缩避免 OutOfMemoryError 内存溢出

当我们使用setImageBitmapsetImageResourceBitmapFactory.decodeResource来设置显示一张大图的时候,经常会遇到 OutOfMemoryError 内存溢出的情况,因为这些函数在完成 decode 后,最终都是通过 Java 层的createBitmap来完成的,需要消耗很多内存。

改用先通过BitmapFactory.decodeStream方法,创建出一个 bitmap,再将其设为 ImageView 的 source,因为 decodeStream 是直接调用JNI>>nativeDecodeAsset()来完成 decode,所以无需再使用 Java 层的 createBitmap,从而节省了 Java 层的空间。

下面是BitmapFactory.Options的常用属性:

属性 描述
options.inDither = false 不进行图片抖动处理。
options.inJustDecodeBounds 设置 true 后,decodeFile 并不分配空间,但可计算出原始图片的长度和宽度,即 opts.widthopts.height。有了这两个参数,再通过一定的算法,即可得到一个恰当的 inSampleSize。
options.inTempStorage 设置缓存大小。
options.inSampleSize 对大图片进行压缩的比例。
options.inPreferredConfig 设置图片的解码方式默认是 Bitmap.Config.ARGB_8888,如果设置为 null 则自动选最佳方式解码。
options.outWidth 图片的宽度。
options.outHeight 图片的高度。
options.inPurgeableinInputShareable 同时设置让系统能及时回收内存。
inPurgeable 设置为 True 时,表示系统内存不足时可以被回收,设置为 False 时,表示不能被回收。
inInputShareable 设置是否深拷贝,与 inPurgeable 结合使用,inPurgeable 为 False 时,该参数无意义。

下面是从指定路径取得图片然后进行压缩的方法:

  1. public static Bitmap revitionImageSize(String path) throws IOException {
  2. BufferedInputStream in = new BufferedInputStream(new FileInputStream(
  3. new File(path)));
  4. BitmapFactory.Options options = new BitmapFactory.Options();
  5. options.inDither = false;
  6. options.inPurgeable = true;
  7. options.inInputShareable = true;
  8. options.inTempStorage = new byte[30 * 1024];//30k缓存
  9. options.inPreferredConfig = Bitmap.Config.RGB_565;
  10. BitmapFactory.decodeStream(in, null, options);
  11. in.close();
  12. int i = 0;
  13. Bitmap bitmap = null;
  14. while (true) {
  15. if ((options.outWidth >> i <= 300)
  16. && (options.outHeight >> i <= 300)) {
  17. in = new BufferedInputStream(
  18. new FileInputStream(new File(path)));
  19. options.inSampleSize = (int) Math.pow(2.0D, i);//设置图片压缩比例
  20. options.inJustDecodeBounds = false;
  21. try {
  22. bitmap = BitmapFactory.decodeStream(in, null, options);
  23. } catch (Exception e) {
  24. // TODO: handle exception
  25. }
  26. break;
  27. }
  28. i += 1;
  29. }
  30. return bitmap;
  31. }

(完)