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

作者:燊在锦官城_ 时间:2023-09-07 07:26:12 

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

来源:http://www.jianshu.com/p/9b2fe4c9be17

标签:android,图片,oom
0
投稿

猜你喜欢

  • Java中为什么this可以调用当前实例

    2022-02-19 18:41:39
  • 浅谈SpringBoot中的@Conditional注解的使用

    2021-12-07 16:47:04
  • SpringBoot应用jar包启动原理详解

    2022-07-08 09:45:48
  • Unity Shader实现水墨效果

    2021-08-29 11:05:01
  • 详解Java中restTemplate的使用

    2023-06-19 23:20:29
  • JavaWeb工程中集成YMP框架快速上手

    2023-11-24 12:15:12
  • maven多个plugin相同phase的执行顺序

    2021-07-07 10:33:34
  • C#实现客户端弹出消息框封装类实例

    2022-06-26 17:33:08
  • C#使用List类实现动态变长数组的方法

    2022-11-30 03:44:35
  • springboot返回图片流的实现示例

    2023-11-23 17:30:08
  • C#多线程学习之(二)操纵一个线程的方法

    2022-02-27 08:53:27
  • RecyclerView实现侧滑拖拽功能

    2023-03-10 16:09:50
  • Java Annotation(Java 注解)的实现代码

    2023-01-09 00:36:17
  • Android开发软键盘遮挡登陆按钮的完美解决方案

    2022-05-09 07:44:47
  • SpringMVC响应视图和结果视图详解

    2022-03-07 05:08:37
  • spring cloud 之 客户端负载均衡Ribbon深入理解

    2023-02-15 15:00:58
  • 浅析Java中接口和抽象类的七大区别

    2022-01-16 21:09:36
  • Java读取txt文件中的数据赋给String变量方法

    2022-08-04 22:32:19
  • Android实现透明动画

    2023-02-08 04:45:47
  • Android ViewPager无限循环滑动并可自动滚动完整实例

    2022-09-09 18:26:55
  • asp之家 软件编程 m.aspxhome.com