6

Sto lavorando a un'applicazione Android e sto utilizzando una bitmap per associare un'immagine a un ImageView. Il mio requisito è quello di ruotare quella ImageView e dare un bordo a quella ImageView. L'ho implementato con successo, ma dopo che l'applicazione utilizza questa attività due-tre volte viene visualizzato un errore di "chiusura forzata" che dice Bitmap fuori dalla memoria della VM. Aiutatemi a ridurre al minimo il consumo di memoria bitmap nel mio codice. E fammi sapere come modificare il codice per lo stesso?Errore di memoria bitmap esaurita in 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

Ho creato una soluzione JNI che evita l'esaurimento della memoria rimuovendo la barriera di limitazione della dimensione massima dell'heap. [** Ecco un collegamento **] (http://stackoverflow.com/questions/14398670/android-rotating-a-mapmap-using-jni-ndk#comment20033361_14398670) al mio snippet. alcune note: - sostituisci nel codice ogni istanza di "uint16_t" con "uint32_t" (questo è il bug sul mio codice che ti ho chiesto). - input e output bitmap deve essere con 8888 config (che è ARGB) - bitmap di input verrà riciclato durante il processo. - Il codice ruota l'immagine di 90 gradi in senso antiorario. ovviamente è possibile cambiarlo in base a –

risposta

3

Credo che si dovrebbe utilizzare la funzione di ridursi come questo

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

ha funzionato per me e ho evitato Bitmap di eccezione di memoria VM

+1

Hi.Thanks per la risposta. Ma nel metodo ShrinkBitmap passa un parametro File che non ho. – Arun

+1

ma è necessario selezionare un file da alcuni in cui non è possibile utilizzarlo. –

+1

Questo cambierà le dimensioni dell'immagine risultante ... – Caner

1

Provare a spostare il gc() chiamata fino alla fine. Dovrebbe funzionare dopo aver impostato res = null in modo che possa liberare la memoria inutilizzata:

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

in Mainfest file di aggiungere ---> Android: largeHeap: "vero"

+0

Solo una nota per gli altri: ho provato a inserirla nei miei tag '' nel manifest, quello che causa gli errori e non ha funzionato. Ma quando l'ho inserito nei tag '' ha funzionato. Inoltre, dovrebbe essere 'android: largeHeap =" true "'. Usa solo due punti. – Azurespot

0

Basta aggiungere Android: largeHeap = "true "nel file manifest

Rif: largeHeap = vero tag manifest non funziona?

Problemi correlati