软件编程
位置:首页>> 软件编程>> Android编程>> Android 图片处理避免出现oom的方法详解

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

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

标签: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;
 }

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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com