High resolution Image – OutOfMemoryError

Three hints which should help you:

  1. Use this to load your images, from Loading Large Bitmaps Android documentation:

    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
            int reqWidth, int reqHeight) {
    
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
    
        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, 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;
    }
    
  2. Make sure you have only one instance of your Bitmap in memory. After displaying it, call recycle() and set your reference to null. You can use Memory Allocation Tracker to see what is allocated. You can also read HPROF files, as suggested in comments.

  3. By default ARGB_8888 pixel format is used, which means 4 bytes per pixel. Very good article: Bitmap quality, banding and dithering. Your image is JPEG, so it doesn’t have transparency, so you are wasting 1 byte on every pixel for alpha channel. It’s not very probable, but maybe with acceptable quality you can use even more economical format. Take a look at them. Maybe RGB_565 for example. It takes 2 bytes for pixel, so your image would be 50% lighter. You can enable dithering to improve the quality of RGB_565.

Leave a Comment

tech