Load Large Image from server on Android

吃可爱长大的小学妹 提交于 2019-11-28 07:04:45

It is not uncommon for BitmapFactory.decodeFromStream() to give up and just return null when you connect it directly to the InputStream of a remote connection. Internally, if you did not provide a BufferedInputStream to the method, it will wrap the supplied stream in one with a buffer size of 16384. One option that sometimes works is to pass a BufferedInputStream with a larger buffer size like:

BufferedInputStream bis = new BufferedInputStream(is, 32 * 1024);

A more universally effective method is to download the file completely first, and then decode the data like this:

InputStream is = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is, 8190);

ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while ((current = bis.read()) != -1) {
    baf.append((byte)current);
}
byte[] imageData = baf.toByteArray();
BitmapFactory.decodeByteArray(imageData, 0, imageData.length);

FYI, the buffer sizes in this example are somewhat arbitrary. As has been said in other answers, it's a fantastic idea not to keep an image that size in memory longer than you have to. You might consider writing it directly to a file and displaying a downsampled version.

Hope that helps!

Devunwired's answer is right but out of memory error can occur if image size is too large, in that case we will have to scale down image, here is the code to scale down image after DevunWired's download image code

    final BitmapFactory.Options options = new BitmapFactory.Options();

    BufferedInputStream bis = new BufferedInputStream(is, 4*1024);
    ByteArrayBuffer baf = new ByteArrayBuffer(50);
    int current = 0;
    while ((current = bis.read()) != -1) {
        baf.append((byte)current);
    }
    byte[] imageData = baf.toByteArray();

    BitmapFactory.decodeByteArray(imageData, 0, imageData.length, options);
    options.inJustDecodeBounds = true;
    options.inSampleSize = 2; //calculateInSampleSize(options, 128, 128);
    options.inJustDecodeBounds = false;
    Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length, options);

Does it silently fail, or does it throw an exception or OutOfMemory error? Btw, if a jpeg is 2MB that doesn't mean it'll take up 2MB of memory. 2MB is the compressed size, and since Android is working with a Bitmap, the 2336 x 3504 will take up approximately 2336 x 3504 x 4 bytes in memory. (2336 x 3504 x 4 = 32,741,376). Downsampling 8 times still might not be enough, especially if you have other bitmaps in memory at the time.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!