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; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。