2010-02-03 2 views
20

У меня очень простое приложение с одним ImageView и кнопкой. Первый ресурс Drawable, загруженный моим ImageView, указан в теге «android: src» в макете XML, однако во время выполнения я хочу, чтобы изменил отображаемый им снимок. Для этого я запускаю операцию для получения изображения с SD-карты (намерение отправлено в MediaStore.Images.Media.EXTERNAL_CONTENT_URI). Однако при выборе картины, я пытаюсь обновить ImageView с URI выбрали картинку, но я получаю сообщение «java.lang.OutOfMemoryError: размер растрового изображения превышает бюджет VM»Изменение содержания образа Image вызывает OutOfMemoryError

I'am пытается загрузить фотографии, сделанные с камерой (размер картинки около 1,1 м) моего HTC-Hero, но без успеха, похоже, работает только с изображениями, размер которых меньше 500 КБ. Однако мне нужно загружать снимки, сделанные камерой. Как я могу это решить? что я делаю неправильно. Мне кажется, что код очень прост и должен работать.

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. это единственное, что должно делать приложение, я не создаю другие объекты, поэтому я хотел бы указать, что я не использую пустое место для других вещей, кроме отображения изображения.

ответ

43

Кажется, что перед загрузкой нового растрового изображения мне пришлось переработать растровое изображение, отображаемое ImageView, теперь оно работает без проблем. Надеюсь, что это поможет кому-то другому, просто вызовите следующий метод, прежде чем устанавливать новый контент ImageView.

((BitmapDrawable)imageView.getDrawable()).getBitmap().recycle();

поэтому код теперь выглядит следующим образом:

@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; 
    } 
} 

Пожалуйста, обратите внимание на вызов для переработки на Bitmap в ImageView.

2

Проблема была решена. , а не только одна строка:

((BitmapDrawable)imageView.getDrawable()).getBitmap().recycle(); 

добавить этот код перед обновлением контента ImageView:

Drawable toRecycle= gallerypic.getDrawable(); 
if (toRecycle != null) { 
    ((BitmapDrawable)gallerypic.getDrawable()).getBitmap().recycle(); 
} 
gallerypic.setImageURI(selectedimage); 
6

Это сводит меня с ума.

Я строию Xoom с очень большими, привет-res, полноэкранными изображениями (800x1232).

Следующий код работает для меня:

public void onStop() 
{ 
    super.onStop(); 
    imageView.setImageBitmap(null); 
} 

Удачи !!!

+0

Этот метод позволит вам сэкономить, если вы используете FragmentStatePagerAdapter с ImageViews, поскольку переработка растрового изображения приведет к ошибке при повторном раздутии представления. –

1

только использовать это перед обновлением imageview: imageView1.setImageURI (null);

1

Я использовал каждое решение этого сообщения и многое другое, но никто не работал. Наконец, я использовал android:largeHeap="true" в манифесте, и это решает мою проблему.

Надеюсь, это поможет кому-то.

Смежные вопросы