如何解决bitmap 内存溢出out of memory的问题

 我来答
huanglenzhi
2014-12-26 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数:117538 获赞数:517183
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。

向TA提问 私信TA
展开全部
  很多人在android开发中都遇到了生成bitmap时候内存溢出,也就是out of memory(OOM)的问题,网上对这样的问题的的解决说法不一。笔者作为一个初级开发者,在这里向大家提供一种比较实用,比较易于理解的方法,这种方法不如一些高级开发者提出的方案来的深刻,但是也能帮助大家有效地解决问题。
  废话不多说了,直接上代码。

  Java代码
  BitmapFactory.Options opt = new BitmapFactory.Options();
  //这个isjustdecodebounds很重要
  opt.inJustDecodeBounds = true;
  bm = BitmapFactory.decodeFile(absolutePath, opt);
  
  //获取到这个图片的原始宽度和高度
  int picWidth = opt.outWidth;
  int picHeight = opt.outHeight;
  
  //获取屏的宽度和高度
  WindowManager windowManager = getWindowManager();
  Display display = windowManager.getDefaultDisplay();
  int screenWidth = display.getWidth();
  int screenHeight = display.getHeight();
  
  //isSampleSize是表示对图片的缩放程度,比如值为2图片的宽度和高度都变为以前的1/2
  opt.inSampleSize = 1;
  //根据屏的大小和图片大小计算出缩放比例
  if(picWidth > picHeight){
  if(picWidth > screenWidth)
  opt.inSampleSize = picWidth/screenWidth;
  }
  else{
  if(picHeight > screenHeight)
  
  opt.inSampleSize = picHeight/screenHeight;
  }
  
  //这次再真正地生成一个有像素的,经过缩放了的bitmap
  opt.inJustDecodeBounds = false;
  bm = BitmapFactory.decodeFile(absolutePath, opt);
  
  //用imageview显示出bitmap
  iv.setImageBitmap(bm);

  BitmapFactory.Options opt = new BitmapFactory.Options();
  //这个isjustdecodebounds很重要
  opt.inJustDecodeBounds = true;
  bm = BitmapFactory.decodeFile(absolutePath, opt);

  //获取到这个图片的原始宽度和高度
  int picWidth = opt.outWidth;
  int picHeight = opt.outHeight;

  //获取屏的宽度和高度
  WindowManager windowManager = getWindowManager();
  Display display = windowManager.getDefaultDisplay();
  int screenWidth = display.getWidth();
  int screenHeight = display.getHeight();

  //isSampleSize是表示对图片的缩放程度,比如值为2图片的宽度和高度都变为以前的1/2
  opt.inSampleSize = 1;
  //根据屏的大小和图片大小计算出缩放比例
  if(picWidth > picHeight){
  if(picWidth > screenWidth)
  opt.inSampleSize = picWidth/screenWidth;
  }
  else{
  if(picHeight > screenHeight)

  opt.inSampleSize = picHeight/screenHeight;
  }

  //这次再真正地生成一个有像素的,经过缩放了的bitmap
  opt.inJustDecodeBounds = false;
  bm = BitmapFactory.decodeFile(absolutePath, opt);

  //用imageview显示出bitmap
  iv.setImageBitmap(bm);

  inJustDecodeBounds 的介绍
  public boolean inJustDecodeBounds
  Since: API Level 1
  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.

  就是说,如果设置inJustDecodeBounds为true,仍可以获取到bitmap信息,但完全不用分配内存,因为没有获取像素,所以我们可以利用得到的Bitmap的大小,重新压缩图片,然后在内存中生成一个更小的Bitmap,这样即便是一个4MB的JPG,我们也可以随心所欲地把他压缩到任意大小,从而节省了内存,看到这里是不是恍然大悟,牛b了牛b了!

  下面这个参数就是跟压缩图片有关的部分,很容易懂,不多解释了:

  inSampleSize 的介绍
  public int inSampleSize
  Since: API Level 1
  If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. The sample size is the number of pixels in either dimension that correspond to a single pixel in the decoded bitmap. For example, inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 the number of pixels. Any value
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2014-12-26
展开全部
很多人在android开发中都遇到了生成bitmap时候内存溢出,也就是out of memory(OOM)的问题,网上对这样的问题的的解决说法不一。笔者作为一个初级开发者,在这里向大家提供一种比较实用,比较易于理解的方法,这种方法不如一些高级开发者提出的方案来的深刻,但是也能帮助大家有效地解决问题。
废话不多说了,直接上代码。
Java代码
BitmapFactory.Options opt = new BitmapFactory.Options();
//这个isjustdecodebounds很重要
opt.inJustDecodeBounds = true;
bm = BitmapFactory.decodeFile(absolutePath, opt);

//获取到这个图片的原始宽度和高度
int picWidth = opt.outWidth;
int picHeight = opt.outHeight;

//获取屏的宽度和高度
WindowManager windowManager = getWindowManager();
Display display = windowManager.getDefaultDisplay();
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();

//isSampleSize是表示对图片的缩放程度,比如值为2图片的宽度和高度都变为以前的1/2
opt.inSampleSize = 1;
//根据屏的大小和图片大小计算出缩放比例
if(picWidth > picHeight){
if(picWidth > screenWidth)
opt.inSampleSize = picWidth/screenWidth;
}
else{
if(picHeight > screenHeight)

opt.inSampleSize = picHeight/screenHeight;
}

//这次再真正地生成一个有像素的,经过缩放了的bitmap
opt.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(absolutePath, opt);

//用imageview显示出bitmap
iv.setImageBitmap(bm);
BitmapFactory.Options opt = new BitmapFactory.Options();
//这个isjustdecodebounds很重要
opt.inJustDecodeBounds = true;
bm = BitmapFactory.decodeFile(absolutePath, opt);

//获取到这个图片的原始宽度和高度
int picWidth = opt.outWidth;
int picHeight = opt.outHeight;

//获取屏的宽度和高度
WindowManager windowManager = getWindowManager();
Display display = windowManager.getDefaultDisplay();
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();

//isSampleSize是表示对图片的缩放程度,比如值为2图片的宽度和高度都变为以前的1/2
opt.inSampleSize = 1;
//根据屏的大小和图片大小计算出缩放比例
if(picWidth > picHeight){
if(picWidth > screenWidth)
opt.inSampleSize = picWidth/screenWidth;
}
else{
if(picHeight > screenHeight)

opt.inSampleSize = picHeight/screenHeight;
}

//这次再真正地生成一个有像素的,经过缩放了的bitmap
opt.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(absolutePath, opt);

//用imageview显示出bitmap
iv.setImageBitmap(bm);
inJustDecodeBounds 的介绍
public boolean inJustDecodeBounds
Since: API Level 1
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.

就是说,如果设置inJustDecodeBounds为true,仍可以获取到bitmap信息,但完全不用分配内存,因为没有获取像素,所以我们可以利用得到的Bitmap的大小,重新压缩图片,然后在内存中生成一个更小的Bitmap,这样即便是一个4MB的JPG,我们也可以随心所欲地把他压缩到任意大小,从而节省了内存
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式