开发者

createBitmap causes an outofmemory error

In my app, I am creating a bitmap from its colors code like this :

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开发者_JS百科++;
}

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

And often I get the outofmemoryerror :( So how can I use the BitmapFactory optimisation to avoid this problem? because I don't have an input stream or a file, I only have an array containing my pixels

Thank you


Couple of things....

Android has really serious problems with bitmaps. They're allocated in non-garbage collected memory.Which is fine. They do get garbage-collected when the owning Bitmap gets collected. What they don't do is relocate while the heap is being compacted. This can cause premature out-of-memory errors due to heap fragmentation. The solution: call Bitmap.recycle as soon as you're done with a bitmap. This frees the non-gc memory, and reduces fragmentation problems.

You can also reduce memory pressure by creating an empty bitmap, and then copying pixels in row by row from a single small buffer. Java gc doesn't particularly like huge arrays either (although large arrays can be relocated during a gc). The performance hit is tiny, and negligible compared to the performance hit from a premature garbage collect. Doing that will reduce your memory usage 49.99 percent.


Try downsampling your image as shown here


please decode the file first,for this use this 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;
        }

    }

You can use android:largeHeap="true" to request a larger heap size mention this in manifest file to use large heap.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜