2011-07-18 34 views
0

我在Gallery View中使用了以下代碼,並且出現以下異常。任何人都可以告訴我我錯在哪裏?Android中的位圖大小超過虛擬機預算

07-18 12:45:59.774: WARN/System.err(6758): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
07-18 12:45:59.774: WARN/System.err(6758):  at android.graphics.Bitmap.nativeCreate(Native Method) 
07-18 12:45:59.774: WARN/System.err(6758):  at android.graphics.Bitmap.createBitmap(Bitmap.java:468) 
07-18 12:45:59.774: WARN/System.err(6758):  at android.graphics.Bitmap.createBitmap(Bitmap 

我的代碼:

public boolean createReflectedImages() { 
    //The gap we want between the reflection and the original image 
    final int reflectionGap = 4; 

    int index = 0; 
    for (int imageId : mImageIds) { 
     try 
     { 
      BitmapFactory.Options options = new BitmapFactory.Options(); 
      options.inTempStorage = new byte[16*1024]; 

      Bitmap originalImage = BitmapFactory.decodeResource(getResources(), 
          imageId,options); 
      int width = originalImage.getWidth(); 
      int height = originalImage.getHeight(); 

      //This will not scale but will flip on the Y axis 
      Matrix matrix = new Matrix(); 
      matrix.preScale(1, -1); 

      //Create a Bitmap with the flip matrix applied to it. 
      //We only want the bottom half of the image 
      reflectionImage = Bitmap.createBitmap(originalImage, 0, height/2, width, height/2, matrix, false); 


      //Create a new bitmap with same width but taller to fit reflection 
      bitmapWithReflection = Bitmap.createBitmap(width 
       , (height + height/2), Config.ARGB_8888); 

      //Create a new Canvas with the bitmap that's big enough for 
      //the image plus gap plus reflection 
      Canvas canvas = new Canvas(bitmapWithReflection); 
      //Draw in the original image 
      canvas.drawBitmap(originalImage, 0, 0, null); 
      //Draw in the gap 
      Paint deafaultPaint = new Paint(); 
      canvas.drawRect(0, height, width, height + reflectionGap, deafaultPaint); 
      //Draw in the reflection 
      canvas.drawBitmap(reflectionImage,0, height + reflectionGap, null); 

      //Create a shader that is a linear gradient that covers the reflection 
      Paint paint = new Paint(); 
      LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0, 
       bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff, 
       TileMode.CLAMP); 
      //Set the paint to use this shader (linear gradient) 
      paint.setShader(shader); 
      //Set the Transfer mode to be porter duff and destination in 
      paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); 
      //Draw a rectangle using the paint with our linear gradient 
       canvas.drawRect(0, height, width, 
       bitmapWithReflection.getHeight() + reflectionGap, paint); 
      ImageView imageView = new ImageView(mContext); 
      imageView.setImageBitmap(bitmapWithReflection); 
      imageView.setLayoutParams(new CoverFlow.LayoutParams(200, 280)); 
      imageView.setScaleType(ScaleType.MATRIX); 
      mImages[index++] = imageView; 
     }catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
    return true; 
} 
+0

http://stackoverflow.com/questions/1949066/java-lang-outofmemoryerror-bitmap-size-exceeds-vm-budget-android的重複? – THelper

回答

3

機會是要加載的超過了你的Android應用程序的RAM限制的圖像。您在加載圖像時應該使用inSampleSize,以便在佔用所有內存之前將其縮小。我用這個功能來加載所有我的圖片:

public static Bitmap decodeFile(File file, int size){ 
    try { 
     //Decode image size 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inPurgeable = true; 
     o.inInputShareable = true; 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeStream(new FileInputStream(file),null,o); 

     //The new size we want to scale to 
     final int REQUIRED_SIZE = size; 

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

     //Decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize=scale; 
     return BitmapFactory.decodeStream(new FileInputStream(file), null, o2); 
    } catch (FileNotFoundException e) {} 
    return null; 
} 

裏面還有幾個額外的選項,但大一個你的問題是inSampleSize它必須是2希望這有助於的功率。

+0

儘管這可能有助於獲得每位圖使用的內存量,但如果分配*太多*位圖,仍然可能導致內存不足。在OP的問題中不清楚分配了多少圖像。 –

+0

+1使用BitmapFactory.Options.inJustDecodeBounds,將節省大量的內存,而不是OP的BitmapFactory.Options.inTempStorage =新字節[16 * 1024]; –

+0

@Daniel你傳入的int大小是多少? – Blundell

相關問題