6

Estoy trabajando en una aplicación de Android y estoy usando un mapa de bits para vincular una imagen a un ImageView. Mi requisito es rotar ese ImageView y darle un borde a ese ImageView. Lo he implementado con éxito, pero después de que la aplicación utiliza esta actividad, dos o tres veces aparece un error de "cierre forzado" diciendo Bitmap out of VM memory. Ayúdame a minimizar el consumo de memoria de mapa de bits en mi código. ¿Y dejarme saber cómo modificar el código para el mismo?Error de memoria de mapa de bits en Android ...

final int BORDER_WIDTH = 5; 
     // Set the border color 
     final int BORDER_COLOR = Color.WHITE; 
     Bitmap res = Bitmap.createBitmap(CAPTURE_IMAGE.getWidth() + 2 
       * BORDER_WIDTH, CAPTURE_IMAGE.getHeight() + 2 * BORDER_WIDTH, 
       CAPTURE_IMAGE.getConfig()); 
     System.gc(); 
     Canvas canvas = new Canvas(res); 
     Paint paint = new Paint(); 
     paint.setColor(BORDER_COLOR); 
     canvas.drawRect(0, 0, res.getWidth(), res.getHeight(), paint); 

     canvas.drawBitmap(CAPTURE_IMAGE, BORDER_WIDTH, BORDER_WIDTH, paint); 
     Matrix mat = new Matrix(); 
     // Set the Imageview position 
     mat.postRotate(355); 

     bMapRotate = Bitmap.createBitmap(res, 0, 0, res.getWidth(), 
       res.getHeight(), mat, true); 
     System.gc(); 
     res.recycle(); 
     res = null; 
     paint = null; 
     canvas = null; 
     mat = null; 
     // Set the captured bitmap image in the imageview 
     mShareImageView.setImageBitmap(bMapRotate); 
+1

He creado una buena solución JNI que evita la falta de memoria al eliminar la barrera de limitación del tamaño máximo de almacenamiento dinámico. [** aquí hay un enlace **] (http://stackoverflow.com/questions/14398670/android-rotating-a-bitmap-using-jni-ndk#comment20033361_14398670) en mi fragmento. algunas notas: - reemplace en el código cada instancia de "uint16_t" con "uint32_t" (ese es el error en mi código que he preguntado). - el mapa de bits de entrada y salida debe estar con la configuración 8888 (que es ARGB) - el mapa de bits de entrada se reciclará durante el proceso. - el código gira la imagen 90 grados en sentido antihorario. por supuesto puede cambiarlo dependiendo de –

Respuesta

3

creo que se debe utilizar la función de reducir el tamaño como esto

bMapRotate = Bitmap.createBitmap(res, 0, 0, res.getWidth(), 
       res.getHeight(), mat, true); 


Bitmap myBitmap = ShrinkBitmap(bMapRotate , 300, 300); 

mShareImageView.setImageBitmap(myBitmap); 


private Bitmap ShrinkBitmap(String file, int width, int height) { 
     // TODO Auto-generated method stub 
     BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); 
     bmpFactoryOptions.inJustDecodeBounds = true; 
     Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions); 

     int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height); 
     int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width); 

     if (heightRatio > 1 || widthRatio > 1) 
     { 
     if (heightRatio > widthRatio) 
     { 
      bmpFactoryOptions.inSampleSize = heightRatio; 
     } else { 
      bmpFactoryOptions.inSampleSize = widthRatio; 
     } 
     } 

     bmpFactoryOptions.inJustDecodeBounds = false; 
     bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions); 
    return bitmap; 
    } 

que trabajó para mí y me evitó mapa de bits de VM excepción de memoria

+1

Hola. Gracias por la respuesta. Pero en el método ShrinkBitmap pasa un archivo de parámetro que no tengo. – Arun

+1

pero debe estar recogiendo archivos de donde no puede usar eso –

+1

Esto cambiará el tamaño de la imagen resultante ... – Caner

1

Trate de mover la llamada gc() hasta el final. Debería funcionar después de establecer res = null para que pueda liberar la memoria no utilizada:

res.recycle(); 
    res = null; 
    paint = null; 
    canvas = null; 
    mat = null; 
    System.gc(); 
3

en el archivo mainfest añadir ---> android: largeHeap: "true"

+0

Solo una nota para los demás: Intenté poner esto en mis etiquetas '' en el manifiesto, el que causaba los errores, y no funcionó. Pero cuando lo puse en las etiquetas '' funcionó. Además, debe ser 'android: largeHeap =" true "'. Solo usa un punto – Azurespot

0

Sólo tiene que añadir androide: largeHeap = "true "en su archivo de manifiesto

Ref: largeHeap = true ¿la etiqueta manifest no funciona?

Cuestiones relacionadas