【问题标题】:How is Bitmap.Options.inSampleSize supposed to work?Bitmap.Options.inSampleSize 应该如何工作?
【发布时间】:2016-02-16 08:21:07
【问题描述】:

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

我已经开始四处寻找,发现图像不会像documentation 中描述的那样调整大小:

如果设置的值 > 1,则请求解码器对原始图像进行二次采样,返回较小的图像以节省内存。样本大小是对应于解码位图中的单个像素的任一维度中的像素数。例如,inSampleSize == 4 返回的图像是原始宽度/高度的 1/4,像素数的 1/16。任何

当我运行代码时:

    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

我完全感到困惑。如果您查看字节数,您可能会注意到,

【问题讨论】:

  • 您的资源可能位于特定于密度的目录中,因此也会考虑密度转换。如果您对带有资源的inSampleSize 感到困扰(恕我直言,这本身有点奇怪),请将资源移至drawable/no-dpi/assets/ 或与密度无关的东西。
  • @CommonsWare 你是对的。我的资源在res/drawable。我已将其移至res/drawable-nodpi,但它工作得很好。我应该从哪里了解密度背后的魔力?为什么它会根据inJustDecodeBounds 给出不同的尺寸?我的意思是它不一致。

标签: android image bitmap android-6.0-marshmallow


【解决方案1】:

我确信为什么BitmapFactory 有一个decodeResource() 方法背后有一个愿景。我还没有完全弄清楚那个愿景是什么。

无论如何,使用decodeResource() 并不会消除您拥有的任何密度特定资源的密度转换。因此,如果您在-hdpi 设备上,并且您的可绘制对象的最佳匹配版本在res/drawable-mdpi/inSampleSize 中,那么密度转换都会发生。而且,坦率地说,我还没有花时间试图弄清楚它们是如何结合起来的。

恕我直言,如果您要使用decodeResource(),它应该用于与特定密度无关的东西:将其放入res/drawable-nodpi/。但是,这只是我。

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

一般?有the documentationthe other documentation

特别是关于BitmapFactory?我不知道有任何关于此的文章。

为什么它会根据inJustDecodeBounds 给出不同的大小?

不知道,抱歉。

【讨论】:

    猜你喜欢
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 2017-01-14
    • 2013-05-04
    相关资源
    最近更新 更多