Sakthimuthiah
Sakthimuthiah

Reputation: 2636

How to prevent out of memory exception while trying to convert input stream object into bitmap in android?

I had used following code to convert inputstream object into bitmap. But it returns "out of memory error", and BitmapFactory Options always returns Zero.

S3ObjectInputStream inputStreamReceiptObject = objectReceiptFromAmazonS3
                            .getObjectContent();
Bitmap bitmapImageFromAmazon = null;
                        try {
if (inputStreamReceiptObject != null){
BitmapFactory.Options o = new BitmapFactory.Options();
                                o.inSampleSize = 8;
                                o.inJustDecodeBounds = true;
                                bitmapImageFromAmazon = BitmapFactory.decodeStream(inputStreamReceiptObject,null,o);    // o is always null
                                if(bitmapImageFromAmazon == null){
                                    System.out.println("Bitmap null");
                                }

                            }

Advance Thanks for any help !

SOLUTION : ( Lot of thanks to Honourable Don and Honourable Akshat )

   ByteArrayOutputStream baos = null ;
                                InputStream is1 = null,is2 = null;
                                 try {
                                        baos = new ByteArrayOutputStream();
                                        // Fake code simulating the copy
                                        // You can generally do better with nio if you need...
                                        // And please, unlike me, do something about the Exceptions :D
                                        byte[] buffer = new byte[1024];
                                        int len;
                                        while ((len = inputStreamReceiptObject.read(buffer)) > -1 ) {
                                            baos.write(buffer, 0, len);
                                        }
                                        baos.flush();

                                        // Open new InputStreams using the recorded bytes
                                        // Can be repeated as many times as you wish
                                        is1 = new ByteArrayInputStream(baos.toByteArray()); 
                                        is2 = new ByteArrayInputStream(baos.toByteArray());

                                        bitmapImageFromAmazon = getBitmapFromInputStream(is1,is2);

                                        if(bitmapImageFromAmazon == null)
                                            System.out.println("IMAGE NULL");
                                        else
                                            System.out.println("IMAGE NOT NULL");

                                } catch (Exception e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                } finally {
                                    baos.close();
                                    is1.close();
                                    is2.close();
                                }


    public Bitmap getBitmapFromInputStream(InputStream is1,InputStream is2) throws IOException {
        Bitmap bitmap = null;

             try {
                 //Decode image size
                 BitmapFactory.Options o = new BitmapFactory.Options();
                 o.inJustDecodeBounds = true;
                 BitmapFactory.decodeStream(is1,null,o);

                 //Find the correct scale value. It should be the power of 2.
                 int scale=1;


                 //Decode with inSampleSize
                 BitmapFactory.Options o2 = new BitmapFactory.Options();
                 o2.inSampleSize=scale;
                 bitmap = BitmapFactory.decodeStream(is2, null, o2);
             } catch (Exception e) {
                 e.printStackTrace();
             }

        return bitmap;

    }

Upvotes: 0

Views: 716

Answers (2)

Akshat Agarwal
Akshat Agarwal

Reputation: 2847

Why dont you try and scale the bitmap image down? Thats mostly the reason why your app showed OOM exception

        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inScaled = false;
        o.inJustDecodeBounds = true;
        FileInputStream stream1 = new FileInputStream(f);
        BitmapFactory.decodeStream(stream1, null, o);
        stream1.close();

        // Find the correct scale value. It should be the power of 2.
        final int REQUIRED_SIZE = 70; //This is the max size of the bitmap in kilobytes
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < REQUIRED_SIZE
                    || height_tmp / 2 < REQUIRED_SIZE)
                break;
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }

        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        FileInputStream stream2 = new FileInputStream(f);
        Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
        stream2.close();
        return bitmap;

Upvotes: 1

don
don

Reputation: 121

The Out Of Memory error should be as it says: you do not have enough memory on your device to render the entire image. You need to ensure that the image you're downloading from S3 is not too big for the device.

To help you debug, try running downloading a smaller image to see if you are still receiving the OOM errors

URLConnection conn = new URL("http://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/Victoria_Parade_postcard.jpg/120px-Victoria_Parade_postcard.jpg").openConnection();
InputStream stream = conn.getInputStream();
Bitmap image = BitmapFactory.decodeStream(stream, null, null);

The o you pass into decodeStream is null because of the OOM error (it must have gone out of scope when you examined it in the debugger).

Upvotes: 1

Related Questions