【问题标题】:The minimum value of inSampleSize for loading a large bitmap加载大位图的 inSampleSize 最小值
【发布时间】:2014-09-17 16:48:22
【问题描述】:

在搜索 SO 并阅读大量答案后,我编写了以下代码来获取 inSampleSize 的最小值以对大位图进行下采样:

public Bitmap load(Context context, String image_url) throws Exception {
    BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();

    bitmapOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(image_url, bitmapOptions);

    final float imageSize = (float) bitmapOptions.outWidth * (float) bitmapOptions.outHeight * 4.0f / 1024.0f / 1024.0f; // MB

    bitmapOptions.inSampleSize = (int) Math.pow(2, Math.floor(imageSize / MemoryManagement.free(context)));
    bitmapOptions.inJustDecodeBounds = false;

    return BitmapProcessing.modifyOrientation(BitmapFactory.decodeFile(image_url, bitmapOptions), image_url);
}

public class MemoryManagement {

    public static float free(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        int memoryClass = am.getMemoryClass() - 10;
        if (memoryClass < 1) memoryClass = 1;
        return (float) memoryClass;
    }

}

目标是在没有任何 OutOfMemory 异常的情况下获得位图样本的最大维度。我可以相信这段代码吗?

【问题讨论】:

  • 你能向我解释一下你要做什么吗?
  • @mmlooloo 我需要加载位图并对其应用一些效果。所以我试图找到inSampleSize的最小值以获得位图样本的最大尺寸,没有任何OOM异常。

标签: android bitmap downsampling


【解决方案1】:

我认为你可以将堆测试升级到 16 大多数设备的 Java 堆限制为 16 甚至 24

类似

public class MemoryManagement {

    public static float free(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        int memoryClass = am.getMemoryClass() - 16;
        if (memoryClass < 1) memoryClass = 1;
        return (float) memoryClass;
    }

}

【讨论】:

    【解决方案2】:

    如果堆大小限制为 16MB,Nadir 返回的是 1MB,这意味着您必须将例如 20MB 的图片缩放到 1MB 空间,但您可以使用例如 10MB,因此我的解决方案是动态缩放,这意味着始终使用 0.6 的内存空间无论堆大小如何,您的图像都是 16MB 或 24MB 等:

        public class MemoryManagement {
    
        public static float free(Context context) {
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            int memoryClass = am.getMemoryClass();
            memoryClass = ((memoryClass *3)/5); // use 0.6 of your memory 
            if (memoryClass < 1) memoryClass = 1;
            return (float) memoryClass;
          }
       }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-18
      相关资源
      最近更新 更多