zoukankan      html  css  js  c++  java
  • 转 Android--加载大分辨率图片到内存

      在使用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 }
    复制代码

     

    源码下载

     

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

  • 相关阅读:
    node中npm安装模块的网络问题
    微信开发
    7-49 打印学生选课清单 (25 分) 数据结构与算法题目集(中文)
    7-53 两个有序序列的中位数 (25 分) 数据结构与算法题目集(中文)
    练习4.2 平衡二叉树的根 (25 分) 浙大版《数据结构(第2版)》题目集
    习题4.3 是否二叉搜索树 (25 分) 浙大版《数据结构(第2版)》题目集
    实验3-1 求一元二次方程的根 (20 分) 《C语言程序设计实验与习题指导(第3版)》
    主元素问题
    未出现的最小正整数
    交换两个线性表位置(或循环移动数组元素)
  • 原文地址:https://www.cnblogs.com/deman/p/4260005.html
Copyright © 2011-2022 走看看