1. Check out our companion app, Forums for Android! Download from Google Play

Bitmap out of memory

Discussion in 'Application Development' started by android88, Feb 22, 2010.

  1. android88

    android88 Member
    Thread Starter

    Jan 6, 2010
    Hi, I'm having a problem with Bitmaps that exceed the size of the VM. In my app, the user takes a picture of about 1200x800 with the camera and something is drawn over it after which it is dsplayed on the screen. For this displaying I resize the image to avoid memory problems.

    But when the user chooses to save the image, I want to save not the rescaled image, but the one with the original size, and thats where the problems occur.
    I need to draw on the image, without destroying the original image, so I now make a copy of the image on which I do the drawing and which I save. But that way I have the large image in memory twice together with the small image for displaying, and I get memory problems.

    Below is my code, is there any way to avoid memory problems? (maybe a way to draw on an image without destroying the original image or something, so I won't have to draw on a copy of the image?)

    Code (Text):
    2. try {
    3.     Bitmap originalImage = android.provider.MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
    4.     Context mContext = getApplicationContext();
    5.     Resources res = mContext.getResources();
    6.     int a = icons[currentIcon-1];
    8.     int largeWidth = originalImage.getWidth();
    9.     int largeHeight = originalImage.getHeight();
    10.     int newWidth = transWidth*imageScale;
    11.     int newHeight = transHeight*imageScale;
    13.     Bitmap tempOriginalImage = Bitmap.createBitmap(largeWidth, largeHeight, Bitmap.Config.RGB_565);            
    14.     Canvas saveCanvas = new Canvas(tempOriginalImage);
    15.     Paint paint = new Paint();
    16.     saveCanvas.drawBitmap(originalImage, 0, 0, paint);
    17.     originalImage.recycle();
    18.     int newPositionX = positionX*imageScale;
    19.     int newPositionY = positionY*imageScale;
    21.     Bitmap icon = BitmapFactory.decodeResource(res, a);
    22.     Bitmap largeScaledIcon = Bitmap.createScaledBitmap(icon, newWidth, newHeight, false);
    23.     icon.recycle();
    24.     saveCanvas.drawBitmap(largeScaledIcon, newPositionX, newPositionY, paint);
    25.     largeScaledIcon.recycle();
    27.     FileOutputStream out = new FileOutputStream(f);
    28.     tempOriginalImage.compress(Bitmap.CompressFormat.JPEG, 100, out);
    29.     tempOriginalImage.recycle();
    30.     out.close();
    33. }catch(Exception e) {
    34.     e.printStackTrace();
    35. }


  2. Ecthelion

    Ecthelion Member

    Mar 1, 2010
    It's hard to solve your problem without knowing e.g. a stacktrace that gives the exact location where the OutOfMemoryError occurs, but here are some remarks:
    - originalImage.recycle() renders the original image useless. So if you use that method, then there is basically no point in creating a copy, but you could as well use the original image.
    - In order to save memory you could try to first save a compressed version of the original bitmap, using a lossless format like PNG, to e.g. a ByteArrayOutputStream, then work on the original image and finally restore the content of the original image from the previously saved data. This avoids the memory allocation for a new, large bitmap. OTOH it takes some time for the PNG compression. Just a thought.
  3. android88

    android88 Member
    Thread Starter

    Jan 6, 2010
    Thanks for the remarks :)

    You're right about the recycle of originalImage, i'm not sure what my reasoning was there :S I think that's something I did before I was using the Mediastore and I never changed it. So I can work directly on originalImage and then the image in the mediastore will not change. That should free up enough memory I think :)

Share This Page