Размер растрового изображения превышает бюджет виртуальной машины в Android - PullRequest
0 голосов
/ 18 июля 2011

Я использовал следующий код в Gallery View и получил следующее исключение. Может кто-нибудь показать мне, где я не прав?

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

1 Ответ

3 голосов
/ 18 июля 2011

Скорее всего, загружаемое вами изображение превышает ограничение ОЗУ для вашего приложения Android.Вы должны использовать 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. Надеюсь, этопомогает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...