解决android缩放图片导致OOM的一个方案

转载 2013年12月02日 11:38:32

安卓开发中应用到图片的处理时候,我们通常会怎么缩放操作呢,来看下面的两种做法:

  方法1:按固定比例进行缩放

  在开发一些软件,如新闻客户端,很多时候要显示图片的缩略图,由于手机屏幕限制,一般情况下,我们取图片的缩略图,取缩略图的方法我们可以使用BitmapFactory的decodeFile方法,然后通过传递进去 BitmapFactory.Option类型的参数进行取缩略图,在Option中,属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。但是,如果我们想取固定大小的缩略图就比较困难了,比如,我们想将不同大小的图片取出来的缩略图高度都为200px,同时要保证图片不失真,那我们该怎么办?总不能将原始图片加载到内存中再进行缩放处理吧,要知道在移动开发中,内存是相当宝贵的,一张100K的图片,加载完所占用的内存何止是100K。

经过阅读文档发现,Options中有个属性inJustDecodeBounds,文档中的是这么说的:

  If set to true, the decoder will return null (no bitmap), but the out... fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels.  意思就是说如果该值设为true那么将不返回实际的bitmap对象,不给其分配内存空间但是可以得到一些解码边界信息即图片大小等信息。因此我们可以通过设置inJustDecodeBounds为true,获取到outHeight(图片原始高度)和 outWidth(图片的原始宽度),然后计算一个inSampleSize(缩放值),就可以取图片了,这里要注意的是,inSampleSize 可能等于0,必须做判断。也就是说先将Options的属性inJustDecodeBounds设为true,先获取图片的基本大小信息数据(信息没有保存在bitmap里面,而是保存在options里面),通过options.outHeight和 options. outWidth获取的大小信息以及自己想要到得图片大小计算出来缩放比例inSampleSize,然后紧接着将inJustDecodeBounds设为false,就可以根据已经得到的缩放比例得到自己想要的图片缩放图了。

  实现代码如下:

BitmapFactory.Options options = new BitmapFactory.Options();

  options.inJustDecodeBounds = true;

  // 记得把assets目录下的图片拷贝到SD卡中

  // 由于设置inJustDecodeBounds为true,因此执行下面代码后bitmap为空

  mBitmap = BitmapFactory.decodeFile("/sdcard/image.jpg", options);

  // 计算缩放比例,由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可

  int scale = (int) (options.outHeight / (float) 200);

  // 因为结果为int型,如果相除后值为0.n,则最终结果将是0

  if (scale <= 0)

  {

  scale = 1;

  }

  System.out.println("Scale=" + scale);

  options.inSampleSize = scale;

  options.inJustDecodeBounds = false;

  // 重新读入图片,注意此时已经把options.inJustDecodeBounds设回false

  mBitmap = BitmapFactory.decodeFile("/sdcard/image.jpg", options);

  int width = mBitmap.getWidth();

  int height = mBitmap.getHeight();

  System.out.println(width + " " + height);

  ImageView image = (ImageView) findViewById(R.id.image);

  image.setImageBitmap(mBitmap);

这样我们就可以读取较大的图片而不会出现内存溢出问题了。

如果你想把压缩后的图片保存在sdcard上的话,通过如下代码就可以了:

File file = new File("/sdcard/ruoshui.png");

  try

  {

  //记得添加sdcard读写权限

  FileOutputStream out = new FileOutputStream(file);

  if (mBitmap.compress(Bitmap.CompressFormat.PNG, 100, out))

  {

  out.flush();

  out.close();

  Toast.makeText(MainActivity.this, "保存成功!", Toast.LENGTH_LONG).show();

  }

  }catch (Exception e)

  {

  e.printStackTrace();

  Toast.makeText(MainActivity.this, "保存失败!", Toast.LENGTH_LONG).show();

  }

方法2:按长宽各自比例进行缩放

上面的方法缩放保存是按长宽比例的,我们当然也可以按固定大小进行缩放:

BitmapFactory.Options options = new BitmapFactory.Options();

  options.inJustDecodeBounds = false;

  // 记得把assets目录下的图片拷贝到SD卡中

  // 由于设置inJustDecodeBounds为true,因此执行下面代码后bitmap为空

  mBitmap = BitmapFactory.decodeFile("/sdcard/image.jpg", options);

  int bmpWidth = mBitmap.getWidth();

  int bmpHeight = mBitmap.getHeight();

  // 缩放图片的尺寸

  float scaleWidth = (float) sWidth / bmpWidth; // 按固定大小缩放 sWidth 写多大就多大

  float scaleHeight = (float) sHeight / bmpHeight; //

  Matrix matrix = new Matrix();

  matrix.postScale(scaleWidth, scaleHeight);// 产生缩放后的Bitmap对象

  Bitmap resizeBitmap = Bitmap.createBitmap(mBitmap, 0, 0, bmpWidth, bmpHeight, matrix, false);

  mBitmap.recycle();

  ImageView image = (ImageView) findViewById(R.id.image);

  image.setImageBitmap(resizeBitmap);



android图片加载导致的OOM分析及有效解决办法(BitmapUtils)

android应用尤其是涉及到很多图片处理的经常会遇到OOM(Out Of Memory),为什么会导致OOM,又该如何解决呢?OOM原因分析:android每一个应用都有一个独立的进程,每个进程都是...
  • wlong610
  • wlong610
  • 2016年04月25日 22:08
  • 1713

Android之解决太大太多图片造成的oom

内存溢出 在最近做的工程中发现加载的图片太多或图片过大时经常出现OOM问题,找网上资料也提供了很多方法,但自己感觉有点乱,特此,今天在不同型号的三款安卓手机上做了测试,因为有效果也有结果,今天小马就...
  • a1031359915
  • a1031359915
  • 2015年03月23日 10:10
  • 3842

RecyclerView利用Glide加载大量图片into(Target)导致OOM异常

RecyclerView利用Glide加载大量图片into(Target)导致OOM异常    这是我的第一篇博客,此前很早就有写博客记录自己学习路程的想法,但都由于个人问题而没能实现,今天刚好趁着遇...
  • m0_38079174
  • m0_38079174
  • 2017年04月30日 11:07
  • 4215

Android 图片缩放引起的OOM异常全篇

传输文件,或者设置头像,我们一般都会检查原始图片的大小,作缩放处理。   常用的Java版缩放图片代码: public Bitmap getZoomImage(Bitmap src, int desW...
  • jdsjlzx
  • jdsjlzx
  • 2015年01月13日 10:04
  • 643

Android: 缩放图片文件引起的OOM异常

传输文件,或者设置头像,我们一般都会检查原始图片的大小,作缩放处理。 常用的Java版缩放图片代码: view plaincopy to clipboardprint? ...
  • vrix
  • vrix
  • 2012年06月01日 14:04
  • 939

android图片的打开和缩放时出现oom处理过程

内容如题: 以前对于图片缩放时出现oom,也是束手无策。昨天看了Android_Tutor对于图片处理的文章,今天就斗胆将这部分的内容演习下。 首先创建一个布局文件:用imageview控件加载图...
  • yehui18sui
  • yehui18sui
  • 2013年06月20日 15:59
  • 1072

Android中加载大图片OOM(图片缩放)

在加载大图片时会经常出现OOM
  • zhengxiongwei
  • zhengxiongwei
  • 2016年03月17日 09:24
  • 281

android 加载大图片时报OOM的解决方案

在Android中:   1.一个进程的内存可以由2个部门组成:java 施用内存 ,C 施用内存 ,这两个内存的和必需小于16M,不然就会出现各人熟悉的OOM,这个就是熬头种OOM的情况。 ...
  • a1031359915
  • a1031359915
  • 2013年07月25日 11:38
  • 595

Android之批量加载图片OOM问题解决方案

一、OOM问题出现的场景和原因   一个好的app总少不了精美的图片,所以Android开发中图片的加载总是避免不了的,而在加载图片过程中,如果处理不当则会出现OOM的问题。那么如何...
  • zhangjin12312
  • zhangjin12312
  • 2017年12月06日 15:06
  • 76

[Android游戏开发经验分享]游戏开发中内存溢出的OOM解决方案——内存图片回收机制

题记:最近有点忙,同时自己也有点懒,没有更新博客。今天刚好发现并解决了一个困扰已久的蛋疼问题,跟大家分享一下。 Android内存机制: 现在Android手机端的游戏,有一个非常重要,也是非常难...
  • u012973906
  • u012973906
  • 2014年01月10日 16:36
  • 1105
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:解决android缩放图片导致OOM的一个方案
举报原因:
原因补充:

(最多只允许输入30个字)