Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load Large Image from server on Android

I am trying to display a jpg file from a server into an imageView. When I try to load a smaller image (300x400), there are no problems. But when I try to load a full size picture (2336x3504), the image will not load. The file size of the image is only 2mb. I do not get any errors in logcat and there are no exceptions thrown. It simply won't load the image. I also tried using this:

BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap=BitmapFactory.decodeStream(is,null,options);

This doesn't do anything to help load the large files, but it does resize the smaller image (like it is suppose to). I did add the large picture to my resources and tested it as if it was embedded in the app and it worked fine, just won't work on the server. I have been working all day on this and can't seem to figure out how to load these large pictures. Can anyone help me out with this? Thanks for any info.

Here is the link where I found the above code and have been playing with the other examples but still not getting it to work.

EDIT:

Here is the code I'm using, to load the image:

public static Bitmap getBitmapFromURL(String src) {
    Bitmap bmImg;
    URL myFileUrl = null;

    try {
        myFileUrl = new URL(src);

        HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
        conn.setDoInput(true);
        conn.connect();
        InputStream is = conn.getInputStream();

        BitmapFactory.Options options=new BitmapFactory.Options();
        options.inSampleSize = 16;

        bmImg = BitmapFactory.decodeStream(is, null, options);
        return bmImg;
    } catch (Exception e) {
        // TODO Auto-generated catch block
        Log.d("Error", e.toString());
        return null;
    }
}

Here is the logcat screenshot (couldn't figure out how to copy the text appropriately in eclipse) I cleared the log right before I hit the button to load the image. So all you see is what happens when I hit that button. I erased the company and app names (where you see "com.", assume its "com.mycompany.myapp". Logcat Screenshot

like image 388
Brian Avatar asked Feb 14 '11 19:02

Brian


2 Answers

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!

like image 167
devunwired Avatar answered Sep 19 '22 12:09

devunwired


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);
like image 45
Farooq Avatar answered Sep 21 '22 12:09

Farooq