I have a very simple application with one ImageView and a Button. The first Drawable resource loaded by my ImageView is specified with the "android:src" tag in the XML Layout, however at runtime i want to change the picture displayed by it. To do so i start an Activity for result to pick an image from the sd card (intent sent to MediaStore.Images.Media.EXTERNAL_CONTENT_URI). However when the picture is selected, i try to update the ImageView with the chosen Picture's URI but i get the message "java.lang.OutOfMemoryError: bitmap size exceeds VM budget"
I'am trying to load pictures taken with the camera (pics size are around 1.1M) of my HTC-Hero but no success, seems to work only with pictures that are less than 500KB.However i need to load pictures taken with the camera. How can i solve this? what am I doing wrong. Seem to me that the code is very simple and should work.
public void onClick(View v){
Intent selectImageIntent=new Intent(Intent.ACTION_PICK ,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(selectImageIntent,1);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==Activity.RESULT_OK){
Uri selectedImageUri = data.getData();
Log.i(TAG,"chosen image: "+selectedImageUri.toString());
ImageView imageView = (ImageView) this.findViewById(R.id.ImageView01);
imageView.setImageURI(selectedImageUri);//here I get the OutOfMemoryError
imageView.invalidate();
}else{
//canceled
}
}
p.s. that is the only thing the App should do, I'm not creating other objects so I will like to point out that I am not using heap space for other stuff besides displaying the image.
Seems like before loading a new Bitmap I had to recycle the Bitmap displayed by the ImageView, now it is working without a problem. Hope this helps someone else, just call the folowing method before setting the new ImageView's content.
((BitmapDrawable)imageView.getDrawable()).getBitmap().recycle();
so the code now looks like this:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case INTENT_REQUEST_SELECT_IMAGE:
if(resultCode==Activity.RESULT_OK){
Uri selectedImageUri = data.getData();
Log.i(TAG,"selectedImageUri.getPath()"+selectedImageUri.getPath() );
ImageView imageView = (ImageView) this.findViewById(R.id.ImageView_of_text);
((BitmapDrawable)imageView.getDrawable()).getBitmap().recycle();
imageView.setImageURI(selectedImageUri);
imageView.invalidate();
}else{
//TODO define what to do in case the user canceled OCR or any other event
}
break;
default:
break;
}
}
Please note the call to recycle on the Bitmap of the ImageView.
This was driving me nuts.
I'm building for a Xoom with very large, hi-res, full screen images (800x1232).
The following code worked for me:
public void onStop()
{
super.onStop();
imageView.setImageBitmap(null);
}
Good luck!!!
The problem has now been solved. rather than only one line:
((BitmapDrawable)imageView.getDrawable()).getBitmap().recycle();
add this code before updating ImageView content:
Drawable toRecycle= gallerypic.getDrawable();
if (toRecycle != null) {
((BitmapDrawable)gallerypic.getDrawable()).getBitmap().recycle();
}
gallerypic.setImageURI(selectedimage);
only use this before update imageview: imageView1.setImageURI(null);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With