1

I am processing up to 1200 images. I optimized it to work from 100 images up to 500 with the help of previous questions found here. Now, this is what I have:

   public Bitmap getBitmap(String filepath) {
        boolean done = false;
        int downsampleBy = 2;
        Bitmap bitmap = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filepath, options);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        options.inPreferredConfig = Config.RGB_565;
        while (!done) {
            options.inSampleSize = downsampleBy++;
            try {
                bitmap = BitmapFactory.decodeFile(filepath, options);
                done = true;
            } catch (OutOfMemoryError e) {
                // Ignore.  Try again.
            }
        }
        return bitmap;
    }

This function is called in a loop, and it goes really fast until it hits the 500th image. At this point it slows down, until it finally stops working at around the 600th image.

At this point I don't know how else to optimize it to make it work. What do you think is happening and how can I fix it?

EDIT

            // Decode BItmap considering memory limitations
    public Bitmap getBitmap(String filepath) {
        Bitmap bitmap = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filepath, options);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        options.inPreferredConfig = Config.RGB_565;
        options.inDither = true;
        options.inSampleSize= calculateInSampleSize(options, 160, 120);

        return bitmap = 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) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

Made the changes of the accepted answer. Using the function from Google's tutorials to get the correct sample size. Added largeHeap in the manifest and only calling System.gc() once before I loop through all the images.

apSTRK
  • 477
  • 7
  • 21

1 Answers1

2

First of all, you should never expect to catch an Error. Described here: Java documentation An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch.

There is some help about loading bitmaps: Android Developers | Loading large bitmaps

You can get some more memory by declaring the largeHeap="true" attribute in your Application Manifest.

And also the System.gc() call might help freeing some unused memory, but I won't really rely on that call.

Sipka
  • 2,291
  • 2
  • 27
  • 30
  • I did this after finding it in a StackOverflow answer. I did seem to me like it was not the correct way to go, but it works better than the caculateInSampleSize function from this question: http://stackoverflow.com/questions/21392972/how-to-load-large-images-in-android-and-avoiding-the-out-of-memory-error I will try changing the largeHeap attribute and the System.gc() call and see if it helps @Sipka – apSTRK Jun 22 '14 at 20:37
  • By adding largeHeap and calling System.gc() I got it to process 788 images out of 1200. So it did help, however it crashed at 788 – apSTRK Jun 22 '14 at 20:46
  • You could try calling `System.gc()` every time before you are trying to load an image. The garbage collector will try to free as many memory as possible, including the previous bitmaps which were recycled. – Sipka Jun 22 '14 at 21:10
  • Thank you, that's what I'm doing now. Tested it on my Nexus 5 and all the images are processed, however the device this app will be used in is not working yet. I don't know if this just a hardware limitation is there another way to free more memory? – apSTRK Jun 22 '14 at 21:17
  • 1
    thanks for the help. Since the device is not very powerful I decided to downgrade the quality of the images and it works fine. I'm afraid this is not the final solution since I believe that with more images it would not work. I'm accepting your answer since it's doing what I need now! Thanks again – apSTRK Jun 22 '14 at 21:39