大家好,今天给大家分享的是解决解析图片的出现oom的问题,我们可以用BitmapFactory这里的各种Decode方法,如果图片很小的话,不会出现oom,但是当图片很大的时候

就要用BitmapFactory.Options这个东东了,Options里主要有两个参数比较重要.

  1. options.inJustDecodeBounds = false/true;
  2. //图片压缩比例.
  3. options.inSampleSize = ssize;

我们去解析一个图片,如果太大,就会OOM,我们可以设置压缩比例inSampleSize,但是这个压缩比例设置多少就是个问题,所以我们解析图片可以分为俩个步骤,第一步就是

获取图片的宽高,这里要设置Options.inJustDecodeBounds=true,这时候decode的bitmap为null,只是把图片的宽高放在Options里,然后第二步就是设置合适的压缩比例inSampleSize,这时候获得合适的Bitmap.这里我画了简单的流程图,如下:

为了让大家更容易理解,我这里做了一个简单的demo,主要功能就是一个界面里有个ImageView,点击ImageView的时候,进入本地相册,选择一个图片的时候,ImageView控件显示选择的图片。Demo的步骤如下:

第一步新建一个Android工程命名为ImageCacheDemo.目录结构如下:

第二步新建一个ImageCacheUtil.java工具类,代码如下:

  1. package com.tutor.oom;
  2. import java.io.InputStream;
  3. import android.content.ContentResolver;
  4. import android.content.Context;
  5. import android.graphics.Bitmap;
  6. import android.graphics.BitmapFactory;
  7. import android.graphics.BitmapFactory.Options;
  8. import android.net.Uri;
  9. /**
  10. * @author frankiewei.
  11. * 工具类.
  12. */
  13. public class ImageCacheUtil {
  14. /**
  15. * 获取合适的Bitmap平时获取Bitmap就用这个方法吧.
  16. * @param path 路径.
  17. * @param data byte[]数组.
  18. * @param context 上下文
  19. * @param uri uri
  20. * @param target 模板宽或者高的大小.
  21. * @param width 是否是宽度
  22. * @return
  23. */
  24. public static Bitmap getResizedBitmap(String path, byte[] data,
  25. Context context,Uri uri, int target, boolean width) {
  26. Options options = null;
  27. if (target > 0) {
  28. Options info = new Options();
  29. //这里设置true的时候,decode时候Bitmap返回的为空,
  30. //将图片宽高读取放在Options里.
  31. info.inJustDecodeBounds = false;
  32. decode(path, data, context,uri, info);
  33. int dim = info.outWidth;
  34. if (!width)
  35. dim = Math.max(dim, info.outHeight);
  36. int ssize = sampleSize(dim, target);
  37. options = new Options();
  38. options.inSampleSize = ssize;
  39. }
  40. Bitmap bm = null;
  41. try {
  42. bm = decode(path, data, context,uri, options);
  43. } catch(Exception e){
  44. e.printStackTrace();
  45. }
  46. return bm;
  47. }
  48. /**
  49. * 解析Bitmap的公用方法.
  50. * @param path
  51. * @param data
  52. * @param context
  53. * @param uri
  54. * @param options
  55. * @return
  56. */
  57. public static Bitmap decode(String path, byte[] data, Context context,
  58. Uri uri, BitmapFactory.Options options) {
  59. Bitmap result = null;
  60. if (path != null) {
  61. result = BitmapFactory.decodeFile(path, options);
  62. } else if (data != null) {
  63. result = BitmapFactory.decodeByteArray(data, 0, data.length,
  64. options);
  65. } else if (uri != null) {
  66. //uri不为空的时候context也不要为空.
  67. ContentResolver cr = context.getContentResolver();
  68. InputStream inputStream = null;
  69. try {
  70. inputStream = cr.openInputStream(uri);
  71. result = BitmapFactory.decodeStream(inputStream, null, options);
  72. inputStream.close();
  73. } catch (Exception e) {
  74. e.printStackTrace();
  75. }
  76. }
  77. return result;
  78. }
  79. /**
  80. * 获取合适的sampleSize.
  81. * 这里就简单实现都是2的倍数啦.
  82. * @param width
  83. * @param target
  84. * @return
  85. */
  86. private static int sampleSize(int width, int target){
  87. int result = 1;
  88. for(int i = 0; i < 10; i++){
  89. if(width < target * 2){
  90. break;
  91. }
  92. width = width / 2;
  93. result = result * 2;
  94. }
  95. return result;
  96. }
  97. }

第三步:修改ImageCacheDemoActivity.java代码如下:

  1. package com.tutor.oom;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.graphics.Bitmap;
  5. import android.os.Bundle;
  6. import android.provider.MediaStore;
  7. import android.view.View;
  8. import android.view.View.OnClickListener;
  9. import android.widget.ImageView;
  10. /**
  11. * @author frankiewei.
  12. * 解决图片普通OOM的Demo.
  13. */
  14. public class ImageCacheDemoActivity extends Activity {
  15. /**
  16. * 显示图片的ImageView.
  17. */
  18. private ImageView mImageView;
  19. /**
  20. * 打开本地相册的requestcode.
  21. */
  22. public static final int OPEN_PHOTO_REQUESTCODE =  0x1;
  23. /**
  24. * 图片的target大小.
  25. */
  26. private static final int target = 400;
  27. @Override
  28. public void onCreate(Bundle savedInstanceState) {
  29. super.onCreate(savedInstanceState);
  30. setContentView(R.layout.main);
  31. setupViews();
  32. }
  33. private void setupViews(){
  34. mImageView = (ImageView)findViewById(R.id.imageview);
  35. mImageView.setOnClickListener(new OnClickListener() {
  36. public void onClick(View v) {
  37. openPhotos();
  38. }
  39. });
  40. }
  41. /**
  42. * 打开本地相册.
  43. */
  44. private void openPhotos() {
  45. Intent intent = new Intent(Intent.ACTION_PICK, null);
  46. intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
  47. "image/*");
  48. startActivityForResult(intent, OPEN_PHOTO_REQUESTCODE);
  49. }
  50. @Override
  51. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  52. switch (requestCode) {
  53. case OPEN_PHOTO_REQUESTCODE:
  54. if(resultCode == RESULT_OK){
  55. //如果用这个方法,Options为null时候,就是默认decode会出现oom哦.
  56. //Bitmap bm = ImageCacheUtil.decode(null, null,
  57. //      ImageCacheDemoActivity.this, data.getData(), null);
  58. //这里调用这个方法就不会oom.屌丝们就用这个方法吧.
  59. Bitmap bm = ImageCacheUtil.getResizedBitmap(null, null,
  60. ImageCacheDemoActivity.this, data.getData(), target, false);
  61. mImageView.setImageBitmap(bm);
  62. }
  63. break;
  64. default:
  65. break;
  66. }
  67. super.onActivityResult(requestCode, resultCode, data);
  68. }
  69. }

其中main.xml布局代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical" >
  6. <TextView
  7. android:layout_width="fill_parent"
  8. android:layout_height="wrap_content"
  9. android:text="@string/hello" />
  10. <ImageView
  11. android:id="@+id/imageview"
  12. android:layout_width="400px"
  13. android:layout_height="400px"
  14. android:src="@drawable/ic_launcher"
  15. />
  16. </LinearLayout>

第四步运行上述工程,效果如下:

从本地相册选择显示。用了getRsizedBitmap()方法,图片很大不会oom.

运用默认的decode方法就会oom。

OK,今天就讲到这里,大家有什么疑问的,可以留言,谢谢大家!!!

源代码点击进入==>

转自:链接

解决Android解析图片的OOM问题!!!(转)的更多相关文章

  1. 解决Android中图片圆角——.9图

    目录:  一.问题概述 二..9图介绍 三..9图制作 1.开发工具 2.打开图片 3.制作图片 4.保存图片 一.问题概述 在html开发中,可以通过设置css的border-radius来设置圆角 ...

  2. 每个人都要学的图片压缩终极奥义,有效解决 Android 程序 OOM

    # 由来 在我们编写 Android 程序的时候,几乎永远逃避不了图片压缩的难题.除了应用图标之外,我们所要显示的图片基本上只有两个来源: 来自网络下载 本地相册中加载 不管是网上下载下来的也好,还是 ...

  3. Android 使用Bitmap将自身保存为文件,BitmapFactory从File中解析图片并防止OOM

    1.使用Bitmap将自身保存为文件 public boolean saveBitmapAsFile(String name, Bitmap bitmap) { File saveFile = new ...

  4. 关于android 使用bitmap的OOM心得和解决方式

    android开发,从2010年開始学习到如今的独立完毕一个app,这漫长的四年,已经经历了非常多次bug的折磨.无数次的加班训练.然而,自以为自己已经比較了解android了,却近期在一个项目上.由 ...

  5. Android中解决图像解码导致的OOM问题

    Android中解决图像解码导致的OOM问题 原文链接:http://blog.csdn.net/zjl5211314/article/details/7042017

  6. Zxing图片拉伸解决 Android 二维码扫描

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/aaawqqq/article/details/24852915  二维码扫描  Android Zx ...

  7. Android大图片导致内存问题小结

    在网上看了部分Android中OOM的问题,现在根据理解,做一下笔记. Android OOM 产生的几种原因 1. 程序中使用了太多自己创建的Bitmap. 这种情况通常是最好解决的. 因为你明白你 ...

  8. 彻底解决Android因加载多个大图引起的OutOfMemoryError,内存溢出的问题

    最近因为项目里需求是选择或者拍摄多张照片后,提供滑动预览和上传,很多照片是好几MB一张,因为目前的Android系统对运行的程序都有一定的内存限制,一般是16MB或24MB(视平台而定),不做处理直接 ...

  9. android 有效载荷大图,避OOM

    我们的项目往往会载入图片.有时,承担太多,再装图片,它导致了非常小的程序卡,而在铅oom从而导致异常app再见,今天翻译google官方网站,它已经做了很好的图像处理汇总,由于Google我们已经给解 ...

随机推荐

  1. 7.31 签到,js 全局预处理笔记

    js 解析与执行过程: 一.全局:  1.预处理阶段 : 1.LexicalEnviroment === window {1.预处理 var   |   2.function xxx //预处理申明的 ...

  2. struts2 结果页面配置

    <result>标签: * 属性: * name:逻辑视图的名称 * type:结果页面类型. * dispatcher         :转发.默认值. * redirect       ...

  3. Java集合中Set的常见问题及用法

    在这里演示的案例是衔接Java集合中的List(点击查看)那篇博文的,本节我们学习的Set的用法. Set是Collection的一个重要的子接口,Set中的元素是无序排列的,并且元素不可以重复,被称 ...

  4. ios 中的autoresizingMask

    以前对这个知识理解的不太对,看了下面这个地址的文章后,感觉说的对,也没检验,今天实验后,发现是错的...在这里对以前读过此文的朋友表示抱歉. 原文地址如下: http://www.cnblogs.co ...

  5. 手记-数学分析(高等数学)中有关算法效率的公式列举(O,Θ,Ω)

      权当数据结构与算法分析的学习手记     系数为一的幂级数部分和公式 ∑ n2 = 12 + 22 + 32 + ... + n2 = n(n+1)(2n+1)/6 = O(n3) ∑ n3 =  ...

  6. [Android]drawable-nodpi文件夹 的作用

    把一些不能被拉伸的图片放在 drawable-nodpi 中,此图片将不会被放大,以原大小显示. 看下图: 这两个图片被放到了drawable-nodpi 中 在不同分辨率下的显示大小是一样的,不会被 ...

  7. NHibernate实战详解(一)领域模型设计

    关于NHibernate的资料本身就不多,中文的就更少了,好在有一些翻译文章含金量很高,另外NHibernate与Hibernate的使用方式可谓神似,所以也有不少经验可以去参考Hibernate. ...

  8. 【python】为什么修改全局的dict变量不用global关键字

    转自:http://my.oschina.net/leejun2005/blog/145911?fromerr=qnPCgI19#OSC_h4_8 为什么修改字典d的值不用global关键字先声明呢? ...

  9. python学习 小游戏

    基于python3.4 while循环 #!/usr/bin/python3 #-*- coding=utf-8 -*- import random import sys import os luck ...

  10. July 4th, Week 28th Monday, 2016

    Goals determine what you are going to be. 你的目标决定你将成为怎样的人. What are your goals? What kind of people y ...