在使用ImageView显示图片的时候,直接加载一个图片资源到内存中,经常会出现内存溢出的错误,这是因为有些图片的分辨率比较高,把它直接加载 到内存中之后,会导致堆内存溢出的问题。这篇博客就来讲解一下Android的堆内存以及如何在Android应用中加载一个高分辨率的图片。关于 ImageView不熟悉的朋友,可以看看之前的博客:Android--ImageView。

还原堆内存溢出的错误

  代码如下:

1 btn_loadimage.setOnClickListener(new View.OnClickListener() {
2
3 @Override
4 public void onClick(View v) {
5 Bitmap bitmap=BitmapFactory.decodeFile("/sdcard/a.jpg");
6 iv_bigimage.setImageBitmap(bitmap);
7 }
8 }

分析堆内存溢出

  我们都知道,图片是由一个一个点分布组成的(分辨率),通常加载这类数据都会在内存中创建一个二维数组,数组中的每一项代表一个点,而这个图片的分辨 率是3776 * 2520,每一点又是由ARGB色组成,每个色素占4个Byte,所以这张图片加载到内存中需要消耗的内存为:

  3776 * 2520 * 4byte = 38062080byte

如何加载大分辨率图片

  BitmapFactory.Options为BitmapFactory的一个内部类,它主要用于设定与存储BitmapFactory加载图片的一些信息。下面是Options中需要用到的属性:

        

示例Demo

 1 package cn.bgxt.loadbigimg;
2
3 import android.os.Bundle;
4 import android.os.Environment;
5 import android.app.Activity;
6 import android.graphics.Bitmap;
7 import android.graphics.BitmapFactory;
8 import android.graphics.BitmapFactory.Options;
9 import android.view.Menu;
10 import android.view.View;
11 import android.view.WindowManager;
12 import android.widget.Button;
13 import android.widget.ImageView;
14
15 public class MainActivity extends Activity {
16 private Button btn_loadimage;
17 private ImageView iv_bigimage;
18
19 @Override
20 protected void onCreate(Bundle savedInstanceState) {
21 super.onCreate(savedInstanceState);
22 setContentView(R.layout.activity_main);
23
24 btn_loadimage = (Button) findViewById(R.id.btn_loadimage);
25 iv_bigimage = (ImageView) findViewById(R.id.iv_bigimage);
26
27 btn_loadimage.setOnClickListener(new View.OnClickListener() {
28
29 @Override
30 public void onClick(View v) {
31 // Bitmap bitmap=BitmapFactory.decodeFile("/sdcard/a.jpg");
32 // iv_bigimage.setImageBitmap(bitmap);
33
34 BitmapFactory.Options opts = new Options();
35 // 不读取像素数组到内存中,仅读取图片的信息
36 opts.inJustDecodeBounds = true;
37 BitmapFactory.decodeFile("/sdcard/a.jpg", opts);
38 // 从Options中获取图片的分辨率
39 int imageHeight = opts.outHeight;
40 int imageWidth = opts.outWidth;
41
42 // 获取Android屏幕的服务
43 WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
44 // 获取屏幕的分辨率,getHeight()、getWidth已经被废弃掉了
45 // 应该使用getSize(),但是这里为了向下兼容所以依然使用它们
46 int windowHeight = wm.getDefaultDisplay().getHeight();
47 int windowWidth = wm.getDefaultDisplay().getWidth();
48
49 // 计算采样率
50 int scaleX = imageWidth / windowWidth;
51 int scaleY = imageHeight / windowHeight;
52 int scale = 1;
53 // 采样率依照最大的方向为准
54 if (scaleX > scaleY && scaleY >= 1) {
55 scale = scaleX;
56 }
57 if (scaleX < scaleY && scaleX >= 1) {
58 scale = scaleY;
59 }
60
61 // false表示读取图片像素数组到内存中,依照设定的采样率
62 opts.inJustDecodeBounds = false;
63 // 采样率
64 opts.inSampleSize = scale;
65 Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/a.jpg", opts);
66 iv_bigimage.setImageBitmap(bitmap);
67
68 }
69 });
70 }
71 }

源码下载

  本篇博客到这里就讲解了如何加载一个大分辨率的图片到内存中并使用它。不过一般好一点的图片处理软件,都会有图片放大功能,如果仅做此处理,单纯的把 处理后的图片放大,会影响显示效果,图片还原度不高。一般会重新获取放大区域的图片的分辨率像素数组,然后重新处理加载到内存中进行显示。

转 Android--加载大分辨率图片到内存的更多相关文章

  1. 图片_ _Android--加载大分辨率图片到内存

    http://www.cnblogs.com/plokmju/p/android_LoadBigImage.html#3084005 前言 在使用ImageView显示图片的时候,直接加载一个图片资源 ...

  2. Android--加载大分辨率图片到内存

    前言 在使用ImageView显示图片的时候,直接加载一个图片资源到内存中,经常会出现内存溢出的错误,这是因为有些图片的分辨率比较高,把它直接加载到内存中之后,会导致堆内存溢出的问题.这篇博客就来讲解 ...

  3. Android开发之多媒体编程之加载大分辨率图片

    Android中图片占用内存的大小=图片的总像数*每个像数占用的大小. Android保存图片像素信息使用ARGB,意思是每个像素占用4个字节. 以分辨率为2400*3200的图片来说,加载到Andr ...

  4. Android学习笔记_51_转android 加载大图片防止内存溢出

    首先来还原一下堆内存溢出的错误.首先在SD卡上放一张照片,分辨率为(3776 X 2520),大小为3.88MB,是我自己用相机拍的一张照片.应用的布局很简单,一个Button一个ImageView, ...

  5. Android -- 加载大图片的方法

    在android中要加载一张大图片到内存中如果通过如下方式进行: Bitmap bitmap= BitmapFactory.decodeFile("/sdcard/a.jpg"); ...

  6. Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)【系列1】

    Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)[系列1] Android在加载或者处理超大巨型图片 ...

  7. Android -- 加载大图片到内存,从gallery获取图片,获取图片exif信息

    1. 加载大图片到内存,从gallery获取图片 android默认的最大堆栈只有16M, 图片像素太高会导致内存不足的异常, 需要将图片等比例缩小到适合手机屏幕分辨率, 再加载. 从gallery ...

  8. Android加载大图片OOM异常解决

      尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图, 因为这些函数在完成decode后,最终都是通过 ...

  9. android 加载大图片

    引用:http://my.eoe.cn/littlebirds/archive/4646.html 尽量不要使用setImageBitmap或setImageResource或BitmapFactor ...

随机推荐

  1. IEE数据库kill指定条件的进程

    需求:IEE数据库临时需要添加一个监控,将command为sleep,time>1800,info为null的进程自动杀掉. 1.杀进程脚本ieekill.sh内容如下 #!/bin/bash ...

  2. Spring MVC全局异常处理与拦截器校检

    在使用Spring MVC进行开发时,总是要对系统异常和用户的异常行为进行处理,以提供给用户友好的提示,也可以提高系统的安全性. 拦截系统响应错误 首先是拦截系统响应错误,这个可以在web.xml中配 ...

  3. [git]通过commit_id找回文件

    git checkout commit_id 这样会切换到这个commit_id的上,文件的内容就是这个commit保存的内容. git checkout -b new_branch_name com ...

  4. (翻译)为你的MVC应用程序创建自定义视图引擎

    Creating your own MVC View Engine For MVC Application 原文链接:http://www.codeproject.com/Articles/29429 ...

  5. .net 根据匿名类生成实体类,根据datatable生成实体类,根据sql生成实体类

    在开发中可能会遇到这几种情况 1.EF或LINQ查询出来的匿名对象在其它地方调用不方便,又懒的手动建实体类 2.通过datatable反射实体需要先建一个类 ,头痛 3.通过SQL语句返回的实体也需要 ...

  6. 轻松了解Spring中的控制反转和依赖注入(一)

    我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达170平方米,重达30吨,到现如今的个人笔记本,事物更加轻量功能却更加丰富,这是事物发展过程中的一个趋势,在技术领域中同样也是如此,企业级Ja ...

  7. [Solution] 1分钟使用log4net

    log4net库是Apache log4j框架在Microsoft .NET平台的实现,是一个帮助程序员将日志信息输出到各种目标(控制台.文件.数据库等)的工具 官网:http://logging.a ...

  8. 团队项目2.0软件改进分析MathAPP

    软件改进分析 在此基础上,进行软件的改进. 首先,我们把这个软件理解成一个投入市场的.帮助小朋友进行算术运算练习的APP. 从质量保证的角度,有哪些需要改进的BUG? 从用户的角度(把自己当成小学生或 ...

  9. C语言字符串匹配函数

    C语言字符串匹配函数,保存有需要时可以用: #include <stdio.h> #include <stdlib.h> #include <string.h> # ...

  10. 【Bootstrap基础学习】05 Bootstrap学习总结

    好吧,Copy了几天,这个总结算是把我对Bootstrap的一些理解写一下吧. Bootstrap只是一套别人写好的前端框架,直接拿来用就好. 不过对于专业的前端而言,如果不去把所有的代码都看一遍来理 ...