6

Pracuję w aplikacji na Androida i używam bitmapy do powiązania obrazu z obrazem. Moim wymaganiem jest obrócenie tego ImageView i nadanie mu granicy do tego ImageView. Udało mi się to zaimplementować, ale po tym, jak aplikacja użyje tego działania, pojawia się dwa-trzy razy błąd "wymuszania zamknięcia", wypowiadający Bitmapę z pamięci VM. Proszę pomóż mi zminimalizować zużycie pamięci bitmapowej w moim kodzie. I daj mi znać, jak zmodyfikować kod dla tego samego?Błąd pamięci bitmap w systemie 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

Stworzyłem ładne rozwiązanie JNI, które pozwala uniknąć braku pamięci, usuwając barierę ograniczającą rozmiar sterty. [** tutaj jest link **] (http://stackoverflow.com/questions/14398670/android-rotating-a-bitmap-using-jni-ndk#comment20033361_14398670) do mojego fragmentu. kilka uwag: - zamień w kodzie każde wystąpienie "uint16_t" na "uint32_t" (to błąd w moim kodzie, o który pytałem). - bitmapa wejściowa i wyjściowa musi być z 8888 config (czyli ARGB) - wejściowa bitmapa zostanie poddana recyklingowi podczas procesu. - kod obraca obraz o 90 stopni w kierunku przeciwnym do zegara. oczywiście możesz to zmienić w zależności od odpowiedzi –

Odpowiedz

3

myślę, że należy użyć funkcji kurczyć się ten

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

pracował dla mnie i unikałem Bitmap z wyjątkiem pamięci VM

+1

. Dziękuję za odpowiedź. W metodzie ShrinkBitmap przekazuje ona parametr Plik, którego nie mam. – Arun

+1

, ale musisz wybrać plik z niektórych, gdzie nie możesz użyć tego –

+1

To zmieni wynikowy rozmiar obrazu ... – Caner

1

Spróbuj przesunąć gc() wezwanie do końca. Powinien działać po ustawieniu res = null tak, że można go zwolnić nieużywaną pamięć:

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

w mainfest pliku dodać ---> android: largeHeap: "true"

+0

Po prostu notatka dla innych: próbowałem umieścić to w moich tagach '' w manifeście, który powodował błędy i nie działał. Ale kiedy umieściłem go w tagach '' zadziałało. Powinien też być "android: largeHeap =" true ". Używaj tylko jednego dwukropka. – Azurespot

0

Wystarczy dodać androida: largeHeap = "true "w pliku manifestu

Ref: largeHeap = true tag manifestu nie działa?

Powiązane problemy