OutofMemoryError: размер растрового изображения превышает бюджет VM (Android)

Получение исключения в BitmapFactory. Не уверен, в чем проблема. (Ну, я могу догадаться, но не знаю, почему это происходит)

  ERROR / AndroidRuntime (7906): java.lang.OutOfMemoryError: размер растрового изображения превышает бюджет VM

 ERROR / AndroidRuntime (7906): at android.graphics.BitmapFactory.decodeFile (BitmapFactory.java:295) 

Мой код довольно прямолинейный. Я определил формат XML с изображением по умолчанию. Я пытаюсь загрузить bm на SDCard (если присутствует – это). Если нет, то отображается изображение по умолчанию. В любом случае .. Вот код:

public class showpicture extends Activity { public void onCreate(Bundle savedInstanceState) { /** Remove menu/status bar **/ requestWindowFeature(Window.FEATURE_NO_TITLE); final Window win = getWindow(); win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); Bitmap bm; super.onCreate(savedInstanceState); setContentView(R.layout.showpicture); try { ImageView mImageButton = (ImageView)findViewById(R.id.displayPicture); bm = Bitmap.createScaledBitmap(BitmapFactory.decodeFile("/sdcard/dcim/Camera/20091018203339743.jpg"),100, 100, true); parkImageButton.setImageBitmap(bm); } catch (IllegalArgumentException ex) { Log.d("MYAPP",ex.getMessage()); } catch (IllegalStateException ex) { 

Он не работает на bm=Bitmap.createScaledBitmap любые мысли? Я сделал некоторые исследования на форумах, и он указал на этот пост, я просто не знаю, почему он не работает. Любая помощь будет замечательной! Благодаря,

Крис.

Solutions Collecting From Web of "OutofMemoryError: размер растрового изображения превышает бюджет VM (Android)"

InSampleSize – хороший намек. Но фиксированное значение часто не работает нормально, так как большие растровые изображения из файлов обычно являются пользовательскими файлами, которые могут варьироваться от маленьких миниатюр до 12-мегапиксельных изображений из digicam.

Вот быстрая и грязная рутина загрузки. Я знаю, что есть возможности для улучшения, например, более качественный кодированный контур, используя полномочия 2 для более быстрого декодирования и т. Д. Но это рабочий старт …

 public static Bitmap loadResizedBitmap( String filename, int width, int height, boolean exact ) { Bitmap bitmap = null; BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile( filename, options ); if ( options.outHeight > 0 && options.outWidth > 0 ) { options.inJustDecodeBounds = false; options.inSampleSize = 2; while ( options.outWidth / options.inSampleSize > width && options.outHeight / options.inSampleSize > height ) { options.inSampleSize++; } options.inSampleSize--; bitmap = BitmapFactory.decodeFile( filename, options ); if ( bitmap != null && exact ) { bitmap = Bitmap.createScaledBitmap( bitmap, width, height, false ); } } return bitmap; } 

Btw, в новых API-интерфейсах также есть много BitmapFactory.Option для подгонки изображения к экранам DPI, но я не уверен, действительно ли они что-то упрощают. Использование android.util.DisplayMetrics.density или просто фиксированный размер для меньшего потребления памяти, похоже, лучше работает imho.

Что касается этой ссылки , обратите внимание, что ошибка outOfMemory может быть решена следующим образом:

 public Bitmap decodeFile(String filePath) { Bitmap bitmap = null; BitmapFactory.Options options = new BitmapFactory.Options(); options.inPurgeable = true; try { BitmapFactory.Options.class.getField("inNativeAlloc").setBoolean(options,true); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } if(filePath != null) { bitmap = BitmapFactory.decodeFile(filePath, options); } return bitmap; } 

Обязательно защитите свое растровое изображение от ошибок из памяти! На большинстве платформ у android не так много памяти, и он быстро заканчивается с растровыми изображениями. Кроме того, убедитесь, что вы как можно больше вручную переработали растровые изображения, я заметил, что сбор мусора может быть довольно медленным.

 try{ Bitmap myFragileBitmap = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888); } catch(IllegalArgumentException e){ Log.e(TAG,"Illegal argument exception."); } catch(OutOfMemoryError e){ Log.e(TAG,"Out of memory error :("); } 

В результате я изменил размер растрового изображения, используя следующий код, который, похоже, решил проблему.

 BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 8; Bitmap preview_bitmap = BitmapFactory.decodeFile(mPathName, options); 

Я думаю, что это – то, что он говорит. Ваше изображение слишком велико, и поскольку оно загружается в поток, когда память исчерпана, генерируется исключение. Это даже не вопрос о том, сколько памяти у вас в целом, но насколько ваша конкретная активность доступна.

Используйте эти параметры в файле decode. Надеюсь, у может собрать растровое изображение, превышающее бюджетную проблему vm.

 BitmapFactory.Options bfOptions=new BitmapFactory.Options(); bfOptions.inDither=false; //Disable Dithering mode bfOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared bfOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future bfOptions.inTempStorage=new byte[32 * 1024]; 

Вы проверили DDMS? С тем, с чем я сталкивался, это, вероятно, не размер изображений, потому что Android, похоже, отлично справляется с большими изображениями. Если вы отслеживаете кучу с помощью DDMS, вы обнаружите, что у вас много свободной памяти. Вы можете «развернуть» свою кучу, добавив это

 static { @SuppressWarnings("unused") byte dummy[] = new byte[ 8*1024*1024 ]; } 

К вашему коду, чтобы заставить кучу расшириться. Это может сделать его немного реже. К сожалению, за исключением того, что он утверждает, что он не может выделить некоторое количество байтов. Скажем 1M. Если вы посмотрите на «свободную» линию, вы увидите, что самый большой блок – >> 1M. Там что-то странное, что я не могу понять. Это не связано даже со скоростью прокручивания изображений. Я видел в каком-то потоке, что вы можете назвать «переработать» или так для растровых изображений. Я до сих пор не понимаю, почему это должно помочь, если размер кучи выше установленного размера.

Я получил эту ошибку, когда начал изменять размер изображения с 320×240 до примерно 64×240 (вниз), а затем импортировал в свой проект (так как я хотел улучшить скорость рендеринга, и до этого момента он содержал много бесполезных альфа-областей).

Теперь последний ответ имеет смысл:

Вы можете «развернуть» свою кучу, добавив этот статический {@SuppressWarnings («неиспользуемый») байтовый макет [] = новый байт [8 * 1024 * 1024]; } К вашему коду, чтобы заставить кучу расшириться. Это может сделать его немного реже.

Я думаю, что это случилось со мной. Android автоматически расшифровывает чертежи в растровые изображения (а затем хранится в куче, все время компиляции?)

Я начал видеть ошибку, когда я использовал меньшую версию моего изображения во время выполнения (я масштабирую их во время выполнения, так как я программирую VGA-игру с ретро-графикой, используя BitmapFactory.decodeResource и Bitmap.createScaledBitmap).

Это должно быть похоже на то, что Марве сказал: «Куча» недостаточно велика в моем случае после сокращения моего рисунка / изображения и импорта его в мой проект.

Я смог избавиться от моего OutOfMemoryException при изменении размера изображения до большего размера (320×240), который проверяет проблему, я думаю?