2011-07-18 19 views
0

Gallery Viewに次のコードを使用しましたが、次の例外があります。私が間違っている場所を誰かに見せてもらえるかビットマップサイズがAndroidでVM予算を超えています

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

は、そこにカップルの余分なオプションがありますが、あなたの問題の大きなものは、このことができます。2.希望の力でなければなりませんinSampleSizeです。

+0

これはビットマップごとに使用されるメモリの量に役立ちますが、*ビットマップをあまりにも多く割り当てるとメモリが不足することがあります。 OPの質問では、いくつのイメージが割り当てられているかは明確ではありません。 –

+0

+1 BitmapFactory.Options.inJustDecodeBoundsを使用すると、OPのBitmapFactory.Options.inTempStorage = new byte [16 * 1024]ではなく、多くのメモリが節約されます。 –

+0

@Danielあなたの渡すintサイズは何ですか? – Blundell

関連する問題