【问题标题】:createBitmap causes an outofmemory errorcreateBitmap 导致内存不足错误
【发布时间】:2011-05-05 15:03:43
【问题描述】:

在我的应用程序中,我正在从它的颜色代码创建一个位图,如下所示:

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

而且我经常遇到内存不足错误:( 那么如何使用 BitmapFactory 优化来避免这个问题呢? 因为我没有输入流或文件,所以我只有一个数组 包含我的像素

谢谢

【问题讨论】:

标签: android memory bitmap out-of-memory


【解决方案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" 请求更大的堆大小 在清单文件中提及这一点以使用大堆。

【讨论】:

    【解决方案2】:

    几件事....

    Android 在位图方面确实存在严重问题。它们被分配在非垃圾收集的内存中。这很好。当拥有的位图被收集时,它们确实会被垃圾收集。他们不做的是在堆被压缩时重新定位。由于堆碎片,这可能会导致过早的内存不足错误。解决方案:使用完位图后立即调用 Bitmap.recycle。这释放了非 gc 内存,并减少了碎片问题。

    您还可以通过创建一个空位图,然后从单个小缓冲区中逐行复制像素来减少内存压力。 Java gc 也不特别喜欢大数组(尽管大数组可以在 gc 期间重新定位)。与过早的垃圾收集对性能的影响相比,性能影响很小,可以忽略不计。这样做会减少 49.99% 的内存使用量。

    【讨论】:

      【解决方案3】:

      尝试按here所示对图像进行下采样

      【讨论】:

        猜你喜欢
        • 2015-11-26
        • 1970-01-01
        • 2014-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多