图片质量压缩避免 OutOfMemoryError 内存溢出
当我们使用setImageBitmap或setImageResource或BitmapFactory.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.width 和 opts.height。有了这两个参数,再通过一定的算法,即可得到一个恰当的 inSampleSize。 |
options.inTempStorage |
设置缓存大小。 |
options.inSampleSize |
对大图片进行压缩的比例。 |
options.inPreferredConfig |
设置图片的解码方式默认是 Bitmap.Config.ARGB_8888,如果设置为 null 则自动选最佳方式解码。 |
options.outWidth |
图片的宽度。 |
options.outHeight |
图片的高度。 |
options.inPurgeable 和 inInputShareable |
同时设置让系统能及时回收内存。 |
inPurgeable |
设置为 True 时,表示系统内存不足时可以被回收,设置为 False 时,表示不能被回收。 |
inInputShareable |
设置是否深拷贝,与 inPurgeable 结合使用,inPurgeable 为 False 时,该参数无意义。 |
下面是从指定路径取得图片然后进行压缩的方法:
public static Bitmap revitionImageSize(String path) throws IOException {BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(path)));BitmapFactory.Options options = new BitmapFactory.Options();options.inDither = false;options.inPurgeable = true;options.inInputShareable = true;options.inTempStorage = new byte[30 * 1024];//30k缓存options.inPreferredConfig = Bitmap.Config.RGB_565;BitmapFactory.decodeStream(in, null, options);in.close();int i = 0;Bitmap bitmap = null;while (true) {if ((options.outWidth >> i <= 300)&& (options.outHeight >> i <= 300)) {in = new BufferedInputStream(new FileInputStream(new File(path)));options.inSampleSize = (int) Math.pow(2.0D, i);//设置图片压缩比例options.inJustDecodeBounds = false;try {bitmap = BitmapFactory.decodeStream(in, null, options);} catch (Exception e) {// TODO: handle exception}break;}i += 1;}return bitmap;}
(完)