zoukankan      html  css  js  c++  java
  • 大图片加载问题理解解决面试官问

    今天来翻译一篇谷歌官方提供的解决方案,原文可以参见:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html 。

    转载:http://www.android100.org/html/201308/04/3880.html。

    个人理解

    BitmapFactory类提供了一些列创建不同图片种类的编码方式,例如:decodeByteArray(), decodeFile(), decodeResource() 等 等。这些编码方法试图为创建Bitmap分配内存,因此可以很容易地导致OutOfMemory异常。通过设置 BitmapFactory.Options的inJustDecodeBounds属性设置为true,可以解码避免内存分配,返回的Bitmap为 空,但返回outWidth,outHeight和outMimeType。这种技术使您可以读取的图像数据的尺寸和类型在内存分配之前。

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

    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
    int imageHeight = options.outHeight;
    int imageWidth = options.outWidth;

    String imageType = options.outMimeType;

    现在的图像尺寸是已知的,它们可以被用来决定是否应加载到内存或二次采样的版本,而不是应装入完整的图像。这里有一些要考虑的因素:

    • 估计载入一张完整图像的内存使用

    • 你愿意投入到这个图片加载应用程序的任何其他内存要求的内存量。

    • 图像要加载到的目标的ImageView或UI组件的尺寸。

    • 当前设备的屏幕大小和密度(这些话比较专业 不会表达的可以记一下,抗翻面试官)   例如,没有必要把一个1024×768像素的图像加载到内存中,如果它最终会被显示在一个ImageView 128×96像素的缩略图。告诉图像解码器,加载到内存中的一个较小的版本,设置BitmapFactory.Options对象中的 inSampleSize。例如,与2048×1536分辨率的图像,设置其inSampleSize为4(即Width为1/4,Height为1 /4,整个图像大小为1/16)将产生一个约512×384的位图。载入到内存使用完整的图像(假设ARGB_8888位图配置)0.75MB,而超过 12MB。这里有一个方法来计算的样本大小目标的宽度和高度上的值:

    • public static int calculateInSampleSize(

    •            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    •      // 图像原始高度和宽度
    •           final int height = options.outHeight;
    •           final int width = options.outWidth;
    •           int inSampleSize = 1;
    •      if (height > reqHeight || width > reqWidth) {
    •                 inSampleSize = Math.round((float)height / (float)reqHeight);
    •         } else {
    •             inSampleSize = Math.round((float)width / (float)reqWidth);
    •        }
    •    }

    •     return inSampleSize;
    • }
    • 注意: inSampleSize 设置为2的平方则编码速度更快更高效。不过,如果你打算在内存或磁盘上的缓存调整过大小的版本,它通常还是值得解码到最合适的图像尺寸,以节省空间。

      设置为true inJustDecodeBounds使用这种方法,首先解码,通过选项,然后解码再次使用新inSampleSize值并inJustDecodeBounds设置为false:

    • public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,

    •         int reqWidth, int reqHeight) {
    •    // 首先设置 inJustDecodeBounds=true 来检查尺寸

      05

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

      06

          options.inJustDecodeBounds = true;

      07

          BitmapFactory.decodeResource(res, resId, options);

      08

      09

          // 计算压缩比例

      10

          options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

       

      12

          // 设置inJustDecodeBounds为false

      13

          options.inJustDecodeBounds = false;

      14

          return BitmapFactory.decodeResource(res, resId, options);

      15

      }

      这种方法使很容易地装入一个ImageView显示一个100×100像素的缩略图任意大尺寸位图,在下面的示例代码所示:

      1

      mImageView.setImageBitmap(

      2

      3

          decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

      ,你可以按照一个类似的过程,使用不同的BitmapFactory.decode*方法来编码其他来源的图像。

    • 感谢原作者。

      

  • 相关阅读:
    [C语言嵌入式系统编程修炼] 软件架构与内存操作篇
    [C陷阱和缺陷] 第2章 语法“陷阱”
    DAO是什么技术
    Java泛型:类型擦除
    Java泛型:泛型类、泛型接口和泛型方法
    定义泛型接口
    java,<E>什么意思?
    java List 去重(两种方式)
    java中List集合及其遍历详解
    java 遍历arrayList的四种方法
  • 原文地址:https://www.cnblogs.com/yizuochengchi2012/p/4669013.html
Copyright © 2011-2022 走看看