0

I have 2 ImageView on my home layout and their content comes from images placed on SD card as shown in below code snippet:

try {
        String tempPath1 = Environment.getExternalStorageDirectory()
                + File.separator + "Clipping_Pictures" + File.separator
                + "06-05-2013_02-06-09pm.png";
        File f = new File(tempPath1);
        Bitmap b = null, b2 = null;
        b = BitmapFactory.decodeFile(f.getPath());

        if (f.exists()) {
            ivClip1.setImageBitmap(b);//ivClip1 is ImageView
        }

        tempPath1 = Environment.getExternalStorageDirectory()
                + File.separator + "Clipping_Pictures" + File.separator
                + "06-05-2013_02-06-33pm.png";
        f = new File(tempPath1);
        b2 = BitmapFactory.decodeFile(f.getPath());

        if (f.exists()) {
            ivClip2.setImageBitmap(b2);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

When I load the app for the 1st time, it displays both the images on respective imageviews. But 2nd launch on-wards, app crashes with following exception:
OutOfMemoryError: bitmap size exceeds VM budget

Note that two resource images are .png and of size ~850kb each which should be fine I guess.

There are similar threads on SO and on internet and I tried some of their suggested solutions, but none seems to work.

Any help appreciated.

GAMA
  • 5,958
  • 14
  • 79
  • 126

4 Answers4

3

If you are building your app for Android 3.0 on wards, then you can use android:largeHeap="true" attribute in your application tag of manifest file. Doing this, hope your app won't crash due to Out of Memory.

Here is example:

application

android:allowBackup="true"
android:icon="@drawable/icon_96x96"
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@android:style/Theme.NoTitleBar" 

Thanks!

Kaushik
  • 6,150
  • 5
  • 39
  • 54
Sudipta Som
  • 6,537
  • 9
  • 43
  • 67
1

Are you executing all this code from onCreate() or from onResume()?

You may try to clean the views before you try to load the images again (ivClip1.setImageBitmap(null) or a lightweight one), because while you are decoding both bitmaps you are still having the previous instances in memory while showing.

DNax
  • 1,413
  • 1
  • 19
  • 29
  • in `onCreate()`. What do u mean by clean the views? – GAMA Jun 05 '13 at 11:09
  • I suggested calling ivClip1.setImageBitmap(null), if that doesn't work, you may try to set a little empty image (for example a marker image that may say "loading") ivClip1.setImageResource(R.drawable.my_little_marker_image); – DNax Jun 05 '13 at 12:01
1

its because of large size of your bitmaps. compress your bitmap using following code:

Bitmap ShrinkBitmap(byte[] file, int width, int height){

         BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
            bmpFactoryOptions.inJustDecodeBounds = true;
            Bitmap bitmap = BitmapFactory.decodeByteArray(file, 0, file.length, bmpFactoryOptions);


            int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
            int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);

            if (heightRatio > 1 || widthRatio > 1)
            {
             if (heightRatio > widthRatio)
             {
              bmpFactoryOptions.inSampleSize = heightRatio;
             } else {
              bmpFactoryOptions.inSampleSize = widthRatio;
             }
            }

            bmpFactoryOptions.inJustDecodeBounds = false;
            bitmap = BitmapFactory.decodeByteArray(file, 0, file.length, bmpFactoryOptions);
         return bitmap;
        }
Sagar Maiyad
  • 12,655
  • 9
  • 63
  • 99
  • 1st parameter is `byte[] file`. If I'm sending `Bitmap bitmap`, then `Bitmap bitmap = BitmapFactory.decodeByteArray(file, 0, file.length, bmpFactoryOptions);` will change to `Bitmap bitmap = BitmapFactory.decodeByteArray(bitmap, bmpFactoryOptions);` , right? – GAMA Jun 05 '13 at 11:28
  • m sorry but I don't have much idea about chat session. Can you give me the chat link? – GAMA Jun 05 '13 at 11:40
  • you havnt chat experience.?? – Sagar Maiyad Jun 05 '13 at 11:44
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/31249/discussion-between-gama-and-segi) – GAMA Jun 05 '13 at 11:54
1

You can add this lines to resize bitmap and then use it

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file),null,options);

Method to calculate samplesize and reduce the bitmap size

private Bitmap decodeFile(File f){
    try {
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

        final int REQUIRED_SIZE=70;

        //Find the correct scale value. It should be the power of 2.
        int scale=1;
        while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
            scale*=2;

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
    return null;
}
Nirali
  • 13,571
  • 6
  • 40
  • 53