用于加载大位图的inSampleSize的最小值

时间:2014-09-17 16:48:23

标签: android bitmap downsampling

在搜索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异常的情况下获取位图样本的最大维度。我可以相信这段代码吗?

2 个答案:

答案 0 :(得分: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;
    }

}

答案 1 :(得分:0)

如果堆大小限制为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;
      }
   }