OutofMemoryError: el tamaño del bitmap excede el presupuesto de VM (Android)

Obtener una excepción en BitmapFactory. No estoy seguro de cuál es el problema. (Bueno, puedo adivinar el problema, pero no estoy seguro de por qué está sucediendo)

  ERROR / AndroidRuntime (7906): java.lang.OutOfMemoryError: el tamaño del bitmap excede el presupuesto de VM

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

Mi código es bastante directo. Definí un diseño XML con una imagen predeterminada. Intento cargar un bm en la tarjeta SD (si está presente, lo es). Si no, muestra la imagen predeterminada. De todos modos … Aquí está el código:

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) { 

Falla en el bm=Bitmap.createScaledBitmap cualesquiera pensamientos? Hice algunas investigaciones en los foros, y señaló a este post , simplemente no sé por qué no está funcionando. ¡Cualquier ayuda sería genial! Gracias,

Chris.

inSampleSize es una buena pista. Pero un valor fijo a menudo no funciona bien, ya que los grandes mapas de bits de los archivos generalmente son archivos de usuario, que pueden variar desde diminutas miniaturas hasta imágenes de 12MP desde la cámara digital.

Aquí hay una rutina de carga rápida y sucia. Sé que hay margen de mejora, como un bucle codificado más agradable, utilizando potencias de 2 para una deencoding más rápida, y así sucesivamente. Pero es un comienzo de trabajo …

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

Por cierto, en las API más nuevas también hay muchas opciones de BitmapFactory.Option para adaptar la imagen a los DPI, pero no estoy seguro de si realmente simplifican algo. Usar android.util.DisplayMetrics.density o simplemente un tamaño fijo para reducir el consumo de memoria parece funcionar mejor.

Con referencia a este enlace , tenga en cuenta que el error outOfMemory se puede resolver de la siguiente manera:

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

¡Asegúrate de proteger la creación de tu bitmap de los errores de memoria! Con la mayoría de las plataformas, Android no tiene mucha memoria para jugar y se ejecuta rápidamente con bitmaps. Además, asegúrese de reciclar manualmente sus mapas de bits tanto como sea posible, me he dado cuenta de que la recolección de basura puede ser bastante lenta.

 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 :("); } 

Terminé cambiando el tamaño del bitmap usando el siguiente código que parece haber resuelto el problema.

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

Creo que es – lo que dice que es. Su imagen es demasiado grande y, dado que se carga en la secuencia cuando se agota la memoria, se lanza la excepción. Ni siquiera es cuestión de cuánta memoria tienes en total, sino de cuánto tiene disponible tu actividad particular.

usa estas opciones en decodefile espero que puedas elementar el bitmap excede el problema de presupuesto 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]; 

¿Has comprobado el DDMS? Con lo que he estado encontrando, probablemente no sea el tamaño de las imágenes, porque Android parece manejar imágenes grandes bastante bien. Si rastrea el montón con DDMS, es posible que tenga mucha memoria libre. Puedes “expandir” tu montón añadiendo esto

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

a su código, para obligar al montón a expandirse. Puede hacerlo un poco menos frecuente. Desafortunadamente, con la excepción, afirma que no puede asignar una cantidad de bytes. Digamos 1M. Si echas un vistazo a la línea “libre”, verás que el bloque más grande es >> 1M. Hay algo extraño allí que no puedo entender. No está relacionado ni siquiera con la velocidad de deslizamiento de imágenes. Vi en un hilo que puede llamar “reciclar” más o menos para bitmaps. Todavía no veo por qué debería ayudar si el tamaño del montón está muy por encima del tamaño tomado.

Obtuve este error cuando comencé a cambiar el tamaño de una imagen de 320×240 a algo así como 64×240 (downscale), luego la importé a mi proyecto (ya que quería mejorar la velocidad de renderizado y contenía muchas regiones alfa inútiles hasta este punto).

ahora la última respuesta tiene mucho sentido:

Puedes “expandir” tu montón agregando este estático {@SuppressWarnings (“no usado”) byte dummy [] = nuevo byte [8 * 1024 * 1024]; } a su código, para obligar al montón a expandirse. Puede hacerlo un poco menos frecuente.

Creo que esto es lo que me pasó. Android decodifica automáticamente dibujables en mapas de bits, (y luego se almacena en un montón, todo el tiempo de comstackción?)

Empecé a ver el error cuando utilicé la versión más pequeña de mi imagen en tiempo de ejecución (los amplié en tiempo de ejecución ya que programé un juego VGA con gráficos retro, usando BitmapFactory.decodeResource y Bitmap.createScaledBitmap).

debe ser como Marve dijo: The Heap no es lo suficientemente grande en mi caso después de reducir mi dibujo / imagen e importarlo a mi proyecto.

Pude deshacerme de OutOfMemoryException al cambiar el tamaño de la imagen a un tamaño mayor (320×240), lo que verifica el problema, supongo.