2010-11-05 6 views
2

Dans mon application, je crée une image bitmap à partir de son code de couleurs comme ceci:CreateBitmap provoque une erreur OutOfMemory

int width=getImageWidth(); 
int height=getImageHeight(); 
int[] array=getbitmap(); 
int[] colorsAsIntegers = new int[width*height]; 
int i = 0; 
int j = 0; 

while (i<width*height*4) { 
colorsAsIntegers[j] = Color.argb(array[i], array[i+1], array[i+2], 
array[i+3]); 
i += 4; 
j++; 
} 

myBitmap=Bitmap.createBitmap(colorsAsIntegers, 
width, 
height, 
Bitmap.Config.ARGB_8888); 

Et souvent, je reçois le OutOfMemoryError :( Alors, comment puis-je utiliser l'optimisation BitmapFactory pour éviter ce problème? parce que je n'ai pas un flux d'entrée ou d'un fichier, je ne contenant un tableau mes pixels

Merci

+0

Quelle est la taille de votre image? Quel appareil rencontrez-vous des problèmes? – I82Much

+0

Il ne crée pas bitmap tout le temps nous obtenons cette erreur. http://stackoverflow.com/a/18625792/2403532 – Narasimha

Répondre

1

Essayez downsampling votre image comme indiqué here

3

Couple de choses ....

Android a des problèmes très sérieux avec bitmaps. Ils sont alloués dans la mémoire non-garbage collection.Which est bien. Ils obtiennent garbage-recueillis lorsque le Bitmap propriétaire est collecté. Ce qu'ils ne font pas, c'est déménager pendant que le tas est compacté. Cela peut provoquer des erreurs prématurées de mémoire insuffisante dues à la fragmentation du tas. La solution: appelez Bitmap.recycle dès que vous avez terminé avec un bitmap. Cela libère la mémoire non-gc et réduit les problèmes de fragmentation.

Vous pouvez également réduire la pression de la mémoire en créant une image bitmap vide, puis en copiant les pixels ligne par ligne à partir d'un seul petit buffer. Java gc n'aime pas particulièrement les énormes tableaux (bien que les grands tableaux puissent être déplacés pendant un gc). Le succès de la performance est minime et négligeable par rapport à la performance d'une collecte prématurée des ordures. Faire cela réduira votre utilisation de la mémoire de 49,99 pour cent.

1

s'il vous plaît Décoder le premier fichier, pour cette utilisation de ce code:

public static Bitmap new_decode(File f) { 

     // decode image size 

     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     o.inDither = false; // Disable Dithering mode 

     o.inPurgeable = true; // Tell to gc that whether it needs free memory, 
           // the Bitmap can be cleared 

     o.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 
     try { 
      BitmapFactory.decodeStream(new FileInputStream(f), null, o); 
     } catch (FileNotFoundException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 

     // Find the correct scale value. It should be the power of 2. 
     final int REQUIRED_SIZE = 300; 
     int width_tmp = o.outWidth, height_tmp = o.outHeight; 
     int scale = 1; 
     while (true) { 
      if (width_tmp/1.5 < REQUIRED_SIZE && height_tmp/1.5 < REQUIRED_SIZE) 
       break; 
      width_tmp /= 1.5; 
      height_tmp /= 1.5; 
      scale *= 1.5; 
     } 

     // decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     // o2.inSampleSize=scale; 
     o.inDither = false; // Disable Dithering mode 

     o.inPurgeable = true; // Tell to gc that whether it needs free memory, 
           // the Bitmap can be cleared 

     o.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 
     // return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
     try { 

//   return BitmapFactory.decodeStream(new FileInputStream(f), null, 
//     null); 
      Bitmap bitmap= BitmapFactory.decodeStream(new FileInputStream(f), null, null); 
      System.out.println(" IW " + width_tmp); 
      System.out.println("IHH " + height_tmp);   
       int iW = width_tmp; 
       int iH = height_tmp; 

       return Bitmap.createScaledBitmap(bitmap, iW, iH, true); 

     } catch (OutOfMemoryError e) { 
      // TODO: handle exception 
      e.printStackTrace(); 
      // clearCache(); 

      // System.out.println("bitmap creating success"); 
      System.gc(); 
      return null; 
      // System.runFinalization(); 
      // Runtime.getRuntime().gc(); 
      // System.gc(); 
      // decodeFile(f); 
     } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      return null; 
     } 

    } 

Vous pouvez utiliser android:largeHeap="true" pour demander une plus grande taille de tas mentionner dans le fichier manifeste d'utiliser un grand tas.

+0

marquer comme réponse s'il guérit @sharktiger – Hamad

Questions connexes