What is wrong with this inSampleSize calculation method for bitmap images? Not enough memory

In my application, I repeat the URLs of the images, decrypting them and putting them in ArrayList<Bitmap>.

They can vary greatly in size, so I do a “preliminary decoding” with the option inJustDecodeBounds = trueto calculate the required value inSampleSizefor the actual decoding.

See my method for this below, I hope this is not too hard to understand. I mainly aim for a size similar to the screen size of the device.

for (Element e: posts) {
    if (!e.id().equals("")) {
        //preparing decode
        options = new BitmapFactory.Options();
        input = new URL(e.url).openStream();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(input, null, options);
        input.close();

        //setting inSampleSize if necessary
        int picPixels = options.outWidth * options.outHeight;
        int picScreenRatio = picPixels / screenPixels;
        if (picScreenRatio > 1) {
            int sampleSize = picScreenRatio % 2 == 0 ? picScreenRatio : picScreenRatio + 1;
            options.inSampleSize = sampleSize;
        }

        //actual decode
        input = new URL(e.url).openStream();
        options.inJustDecodeBounds = false;
        Bitmap pic = BitmapFactory.decodeStream(input, null, options);
        input.close();

        picList.add(pic);
    }
}

Code for calculation screenPixels:

Display display = getWindowManager().getDefaultDisplay();
Point screenSize = new Point();
display.getSize(screenSize);
int screenPixels = screenSize.x * screenSize.y;

I view ~ 60 images and about 40 of my applications are crashed with java.lang.OutOfMemoryError.

, inJustDecodeBounds = true , ( , ), inSampleSize s, , .

.

+4
3

, inSampleSize, 60 .

, 1920*1080*60*4 .

500 . - .

this , . .

.

+2

. :

> 1, , . , . , inSampleSize == 4 , 1/4 / , 1/16 . <= 1 , 1. : 2, 2.

Android - Volley , :

    int findBestSampleSize(int actualWidth, int actualHeight, int desiredWidth, int desiredHeight) {
        double wr = (double) actualWidth / desiredWidth;
        double hr = (double) actualHeight / desiredHeight;
        double ratio = Math.min(wr, hr);
        float n = 1.0f;
        while ((n * 2) <= ratio) {
            n *= 2;
        }

        return (int) n;
    }
+2

, Android. , Facebook Fresco:

https://github.com/facebook/fresco

:

Fresco Drawers , , . , .

:

, Fresco, .

0

All Articles