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

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

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

时间: 2024-08-01 05:57:05

Android 图片处理避免出现oom的方法详解的相关文章

Android编程实现自定义手势的方法详解_Android

本文实例讲述了Android编程实现自定义手势的方法.分享给大家供大家参考,具体如下: 之前介绍过如何在Android程序中使用手势,主要是系统默认提供的几个手势,这次介绍一下如何自定义手势,以及如何对其进行管理. 先介绍一下Android系统对手势的管理,Android系统允许应用程序把用户的手势以文件的形式保存以前,以后要使用这些手势只需要加载这个手势库文件即可,同时Android系统还提供了诸如手势识别.查找及删除等的函数接口,具体如下: 一.加载手势库文件: staticGestureL

Android编程获取GPS数据的方法详解_Android

本文实例讲述了Android编程获取GPS数据的方法.分享给大家供大家参考,具体如下: GPS是Android系统中重要的组成部分,通过它可以衍生出众多的与位置相关的应用. Android的GPS有一个专门的管理类,称为LocationManager,所有的GPS定位服务都由其对象产生并进行控制. 首先需要明确的是,LocationManager类的对象获取并不是直接创建的,而是由系统提供的,具体来说,通过如下方法,为一个LocationManager对象建立一个对象引用: 复制代码 代码如下:

8种android 对话框(Dialog)使用方法详解_Android

本文汇总了android 8种对话框(Dialog)使用方法,分享给大家供大家参考,具体内容如下 1.写在前面 Android提供了丰富的Dialog函数,本文介绍最常用的8种对话框的使用方法,包括普通(包含提示消息和按钮).列表.单选.多选.等待.进度条.编辑.自定义等多种形式,将在第2部分介绍. 有时,我们希望在对话框创建或关闭时完成一些特定的功能,这需要复写Dialog的create().show().dismiss()等方法,将在第3部分介绍. 2.代码示例 2.1 普通Dialog(图

Android编程实现手机拍照的方法详解_Android

本文实例讲述了Android编程实现手机拍照的方法.分享给大家供大家参考,具体如下: 今天弄了差不多一天手机拍照,后来,边弄边想,而且现在也不知道自己知道的这些对不对,首先,如果使用此种方式拍照的话,程序在模拟器中,刚启动就会出问题,不知道什么原因,猜可能是因为是模拟器的原因,目前没有手机进行测试,这一些无法解释,代码如下: Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(in

Android端实现单点登录的方法详解_Android

前言 单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任.单点登录在大型网站里使用得非常频繁,例如像阿里巴巴这样的网站,在网站的背后是成百上千的子系统,用户一次操作或交易可能涉及到几十个子系统的协作,如果每个子系统都需要用户认证,不仅用户会疯掉,各子系统也会为这种重复认证授权的逻辑搞疯掉.实现单点登录说到底就是要解决如何产生和存储那个信任,再就是其他系统如何验证这个信任的有效

Android 蓝牙2.0的使用方法详解_Android

本文为大家分享了Android操作蓝牙2.0的使用方法,供大家参考,具体内容如下 1.Android操作蓝牙2.0的使用流程 (1)找到设备uuid (2)获取蓝牙适配器,使得蓝牙处于可发现模式,获取下位机的socket,并且与上位机建立建立连接,获取获取输入流和输出流,两个流都不为空时,表示连接成功.否则是连接失败. (3).与下位机的socket开始通信. (4).通信结束后,断开连接(关闭流,关闭socket) 2接下来接直接上代码:2.1找到设备uuid(一般厂商都会给开发者提供) 复制

Android中自定义一个View的方法详解_Android

本文实例讲述了Android中自定义一个View的方法.分享给大家供大家参考,具体如下: Android中自定义View的实现比较简单,无非就是继承父类,然后重载方法,即便如此,在实际编码中难免会遇到一些坑,我把自己遇到的一些问题和解决方法总结一下,希望对广大码友们有所帮助. 注意点① 用xml定义Layout时,Root element 最好使用merge 当我们需要继承一个布局比较复杂的ViewGroup(比较多的是LinearLayout.RelativeLayout)时,通常会用xml来

Android重要控件SnackBar使用方法详解_Android

SnackBar是DesignSupportLibrary中的一个重要的控件,用于在界面下面提示一些关键信息,跟Toast不同的地方是SnackBar允许用户向右滑动消除它,同时,也允许在SnackBar中设定一个Action,当用户点击了SnackBar里面的按钮的时候,可以进行一些操作,所以,功能绝对是很强大的.  SnackBar的构造:  // 参数分别是父容器,提示信息,持续时间public static Snackbar make(@NonNull View view, @NonNu

Android更新UI的四种方法详解_Android

前言 相信每位Android开发者们都知道更新UI只能在主线程中进行,若是在子线程执行任务后需要更新UI,则需要借助handler跳转到主线程中.以下介绍几种操作UI的方法. 一.使用Handler的handleMessage() Handler的构造 public Handler() { this(null, false); } public Handler(Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { fina