1

首先,我已经阅读了很多关于内存不足异常的帖子和文章,但没有一篇对我的情况有所帮助。我要做的是从 sd 卡加载图像,但将其缩放到精确的像素大小。

我首先获取图像的宽度和高度并计算样本大小:

    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(backgroundPath, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, getWidth(), getHeight());

这是我获得样本量的方法(尽管它并不真正相关):

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {

    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    // NOTE: we could use Math.floor here for potential better image quality
    // however, this also results in more out of memory issues
    if (height > reqHeight || width > reqWidth) {
        if (width > height) {
            inSampleSize = Math.round((float)height / (float)reqHeight);
        } else {
            inSampleSize = Math.round((float)width / (float)reqWidth);
        }
    }

    return inSampleSize;
}

现在我有了一个样本大小,我将图像从磁盘加载到近似大小(样本大小):

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    options.inPurgeable = true;
    Bitmap bmp = BitmapFactory.decodeFile(backgroundPath, options);

现在,我将创建的这个位图缩放到我需要的确切大小并清理:

    // scale the bitmap to the exact size we need
    Bitmap editedBmp = Bitmap.createScaledBitmap(bmp, (int) (width * scaleFactor), (int) (height * scaleFactor), true); 

    // clean up first bitmap
    bmp.recycle();
    bmp = null;
    System.gc();    // I know you shouldnt do this, but I'm desperate 

上述步骤通常是让我的内存不足异常。有谁知道从磁盘加载精确大小的位图以避免像上面那样创建两个单独的位图的方法?

此外,当用户第二次运行此代码(设置新图像)时,似乎会发生更多异常。但是,我确保卸载从位图创建的可绘制对象,以便在再次运行此代码之前对其进行垃圾收集。

有什么建议么?

谢谢,尼克

4

2 回答 2

2

在您的情况下,执行第一次解码后无需创建中间位图。由于您在画布上绘图,因此您可以使用以下任一方法(您认为最方便的方法)将图像缩放到完美尺寸。

drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)

drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)
于 2013-02-27T20:19:15.023 回答
0

也许这种方法会有所帮助,我想我自己是从 stackoverflow 中提取出来的。它解决了我的内存不足异常问题。

private Bitmap decodeFile(File f){
    try {
        //Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

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

        //Find the correct scale value. It should be the power of 2.
        int scale=1;
        while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
            scale*=2;

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

    return null;
} 
于 2013-02-22T18:36:16.527 回答