Decode File From SdCard android to avoid out of memory error due to large bitmap or setImageURI

Avoid outof memory error for selecting large image file from sdcard or from resource. how can i tackle with this problem?


为避免从位图中选择SD卡中的文件时出错或使用setImageURI到SD卡,请使用以下方法:

public static Bitmap decodeScaledBitmapFromSdCard(String filePath,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, options);

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

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(filePath, options);
}

public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        // Calculate ratios of height and width to requested height and width
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will guarantee
        // a final image with both dimensions larger than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }

    return inSampleSize;
}

you can use inSampleSize to reduce memory occupied.

Here is code

public static Bitmap decodeAndResizeFile(File f) {
    try {
        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f), null, o);

        // The new size we want to scale to
        final int REQUIRED_SIZE = 70;

        // Find the correct scale value. It should be the power of 2.
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
                break;
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }

        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {
    }
    return null;
}

Here, it will decode image using inSampleSize and this code will find the best inSampleSize values for you.

It worked Fine for me.

if you don't want to use above code, You can also use bitmap.recycle() and System.gc() to release unused memory.But, above one works fine for me. You can use either of the two.

objbitmap.recycle();
objbitmap = null;
System.gc();

Hope, this may solve the issue!


This depends on if you know what size you want to end up with or not.

If you know the size:

See the answer by Android_Craker. It is a solid approach to the problem.

If you don't know the size:

In this case you want the image to be as large as will fit in memory. The solution is to loop over the downsample until you find a size that fits: BitmapFactory.Options options = new BitmapFactory.Options();

boolean done = false;
int downsampleBy = 1;
Bitmap bitmap = null;
while (!done) {
    options.inSampleSize = downsampleBy++;
    try {
        bitmap = BitmapFactory.decodeFile(filePath, options);
        done = true;
    catch (OutOfMemoryError e) {
        // Ignore.  Try again.
    }
}
链接地址: http://www.djcxy.com/p/16626.html

上一篇: 在ListView中延迟加载图像

下一篇: 从SD卡android解码文件以避免由于大位图或setImageURI导致的内存不足错误