Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OutOfMemory error while joining large images

I am joining two images using the code below but it throws an OutOfMemory error my images are around 1MB each.

private Bitmap overlayMark(String first, String second)
{
    Bitmap bmp1, bmp2;
    bmp1 = BitmapFactory.decodeFile(first);
    bmp2 = BitmapFactory.decodeFile(second);
    if (bmp1 == null || bmp2 == null)
        return bmp1;

    int height = bmp1.getHeight();
    if (height < bmp2.getHeight())
        height = bmp2.getHeight();

    Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth() + bmp2.getWidth(), height,
            Bitmap.Config.ARGB_8888);// Out of memory
    Canvas canvas = new Canvas(bmOverlay);
    canvas.drawBitmap(bmp1, 0, 0, null);
    canvas.drawBitmap(bmp2, bmp1.getWidth(), 0, null);
    bmp1.recycle();
    bmp2.recycle();
    return bmOverlay;
}

Update: I tried below two answers but it still not allwoing me to create bitmap of such big size the problem is that the resultant bitmap is too large in size around 2400x3200 so its going out of memory.

How can I join large images without running out of memory?

like image 539
ingsaurabh Avatar asked Jun 02 '11 11:06

ingsaurabh


2 Answers

Without loading the image into memory, you CAN get the size of the image, using inJustDecodeBounds. The Bitmap returns null, but all the parameters are set. You can scale down the image accordingly.

If your JPEG images are 1 MiB each, conversion to a BMP will take a lot of memory indeed. You can easily calculate its BMP equivalent by the dimensions of the image. Conversion of such a large image is expected to crash indeed. Android limits its apps to 16 MiB VM only.

Also use RGB_565 instead of ARGB_8888.

So your only solution is: (a) To use BitmapFactory.Options.inSampleSize to scale down the image or (b) Use Android NDK where the 16 MiB limit isn't there.

like image 146
Shumon Saha Avatar answered Nov 06 '22 04:11

Shumon Saha


I use this simple rule of the thumb: the heavy lifting (both memory/CPU) is done on the server.

So write some servlet that takes the image, resizes it to a specified dimension (probably reduces the pixel depth too) and returns the result.

Piece of cake and it works on any mobile device you need.

Good luck!

like image 5
bestsss Avatar answered Nov 06 '22 04:11

bestsss