2010-11-05 92 views
2

在我的應用程序,我創建從它的顏色代碼的位圖是這樣的:createBitmap導致內存不足錯誤

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

我經常得到的OutOfMemoryError :( 那麼,如何使用BitmapFactory優化,以避免這個問題呢? ,因爲我沒有一個輸入流或文件,我只有一個數組 包含我的像素

謝謝

+0

你的形象有多大?你遇到哪種設備問題? – I82Much 2010-11-05 15:57:25

+0

我們得到這個錯誤時並不會創建位圖。 http://stackoverflow.com/a/18625792/2403532 – Narasimha 2013-09-05 00:52:44

回答

1

嘗試下采樣圖像如圖所示here

3

夫婦的事情....

Android有很嚴重的問題,與位圖。他們被分配在非垃圾回收的內存中。沒問題。當擁有的Bitmap被收集時,它們會被垃圾回收。當堆被壓縮時,他們不做的是重新定位。這可能會導致由於堆碎片造成的內存過早錯誤。解決方案:一旦完成位圖,就調用Bitmap.recycle。這釋放了非gc內存,並減少了碎片問題。

您還可以通過創建空位圖,然後從單個小緩衝區逐行復制像素來降低內存壓力。 Java gc並不特別喜歡巨大的數組(雖然大型數組可以在gc期間重新定位)。與過早垃圾收集的性能相比,性能受到的影響很小,而且可以忽略不計。這樣做會減少49.99%的內存使用量。

1

請先驗證碼解碼文件,用於此用途:

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

    } 

您可以使用android:largeHeap="true"要求更大的堆大小 提到這個清單文件,使用一大堆。

+0

將此標記爲答案,如果它healps @sharktiger – Hamad 2013-09-13 05:02:31