Bitmap.Options.inSampleSize应该如何工作?

时间:2015-11-15 00:21:49

标签: android image bitmap android-6.0-marshmallow

初始代码是官方文档:Loading Large Bitmaps Efficiently

我开始四处寻找并发现图片没有像documentation中所述调整大小:

  

如果设置为值>如图1所示,请求解码器对原始图像进行二次采样,返回较小的图像以节省存储器。样本大小是任一维度中对应于解码位图中的单个像素的像素数。例如,inSampleSize == 4返回的图像是原始宽度/高度的1/4,像素数量的1/16。任何值< = 1都被视为1.注意:解码器使用基于2的幂的最终值,任何其他值将向下舍入到最接近的2的幂。

当我运行代码时:

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);
    Log.e(LOG_TAG, "orig img size " + options.outWidth + "x" + 
          options.outHeight);

    // Calculate inSampleSize
    // options.inJustDecodeBounds = false;  // version 2
    for (int i = 2; i<20; i*=2) {
        options.inSampleSize = i;
        Log.d(LOG_TAG, "inSampleSize: " + options.inSampleSize);
        Bitmap b = BitmapFactory.decodeResource(res, resId, options);
        Log.e(LOG_TAG, "img size "+options.outWidth+"x"+options.outHeight);
        if (b != null) {
            Log.e(LOG_TAG, "real img size " + b.getWidth() + "x" +
                  b.getHeight() + " byte count " + b.getByteCount());
            b.recycle();
        }
    }

运行代码(Nexus 5,Android 6.0)的日志:

E/t: view size 1080x1776
E/t: orig img size 2448x3264
D/t: inSampleSize: 2
E/t: img size 1224x1632
D/t: inSampleSize: 4
E/t: img size 612x816
D/t: inSampleSize: 8
E/t: img size 306x408
D/t: inSampleSize: 16
E/t: img size 153x204
D/t: inSampleSize: 32
E/t: img size 228x306
E/t: real img size 228x306 byte count 279072

这很好,现在有了大量文件(inJustDecodeBounds=false):

E/t: view size 1080x1776
E/t: orig img size 2448x3264
D/t: inSampleSize: 2
W/art: Throwing OutOfMemoryError "Failed to allocate a 71912460 byte allocation with 1048576 free bytes and 62MB until OOM"
D/t: inSampleSize: 4
E/t: img size 1836x2448
E/t: real img size 1836x2448 byte count 17978112
D/t: inSampleSize: 8
E/t: img size 918x1224
E/t: real img size 918x1224 byte count 4494528
D/t: inSampleSize: 16
E/t: img size 459x612
E/t: real img size 459x612 byte count 1123632
D/t: inSampleSize: 32
E/t: img size 228x306
E/t: real img size 228x306 byte count 279072

我完全不解。如果查看字节数,可能会注意到,

1 个答案:

答案 0 :(得分:3)

我确信printf("'%-5s'", "Hi");采用BitmapFactory方法的原因背后有一个愿景。我还没弄清楚那个愿景是什么。

无论如何,使用decodeResource()并不能消除您拥有的任何密度特定资源的密度转换。因此,如果您使用decodeResource()设备,并且您的drawable的最佳匹配版本位于-hdpires/drawable-mdpi/,则密度转换将同时发生。而且,坦率地说,我没有花时间试图找出这些结合的确切方式。

恕我直言,如果您打算使用inSampleSize,那么它应该是针对与特定密度无关的内容:将其放在decodeResource()中。但是,那只是我。

  

我应该在哪里了解密度背后的魔力?

一般情况下?有the documentationthe other documentation

具体针对res/drawable-nodpi/?我不知道有关于此的任何内容。

  

为什么它会根据BitmapFactory提供不同的尺寸?

没有头绪,抱歉。