Bitmap out of memory

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

  1. android88

    android88 Member

    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

    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