首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >安卓位图OutOfMemoryError

安卓位图OutOfMemoryError
EN

Stack Overflow用户
提问于 2013-05-22 04:42:17
回答 2查看 4K关注 0票数 1

我的VSD220里有一个OutOfMemoryError (它是一个22英寸的安卓一体机)

代码语言:javascript
复制
for (ImageView img : listImages) {
            System.gc();

            Bitmap myBitmap = BitmapFactory.decodeFile(path);
            img.setImageBitmap(myBitmap);
            img.setOnClickListener(this);
        }

我真的不知道该怎么办,因为这张图片低于最大分辨率。图像大小约为(1000x1000),显示器大小为1920x1080。

有什么帮助吗?(这个foreach循环大约有20个元素,在6个或7个循环之后就会中断。)

非常感谢。

埃兹奎尔。

EN

回答 2

Stack Overflow用户

发布于 2013-05-22 06:22:29

您应该看看Managing Bitmap Memory的培训文档。根据您的操作系统版本,您可以使用不同的技术来管理更多的位图,但您可能无论如何都必须更改您的代码。

特别是,您可能不得不使用"Load a Scaled Down Version into Memory“中代码的修正版本,但我至少发现这一节特别有用:

代码语言:javascript
复制
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;

    if (height > reqHeight || width > reqWidth) {

        // Calculate ratios of height and width to requested height and width
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will guarantee
        // a final image with both dimensions larger than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }

    return inSampleSize;
}



public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

使用此方法,可以轻松地将任意大小的位图加载到显示100x100像素缩略图的ImageView中,如下面的示例代码所示:

代码语言:javascript
复制
mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
票数 1
EN

Stack Overflow用户

发布于 2013-05-22 05:58:57

您确定要将同一位图加载20次吗?你不想加载它一次并将它设置在循环中吗?

尽管如此,无论屏幕分辨率如何,加载1000x1000像素的图像都不能保证正常工作。请记住,1000x1000像素的图像占用1000x1000x4字节=~4MB (如果将其作为ARGB_8888加载)。如果你的堆内存是碎片的/太小,你可能没有足够的空间加载位图。您可能希望研究一下BitmapFactory.Options类,并尝试使用inPreferredConfiginSampleSize

我建议你要么使用DigCamara的建议,决定一个大小,然后加载一个接近这个大小的下采样图像(我说几乎是因为使用这种技术你不会得到确切的大小),要么尝试加载完整大小的图像,然后递归增加样本大小(为了获得最佳结果,递归增加2倍),直到达到最大样本大小或加载图像:

代码语言:javascript
复制
/**
 * Load a bitmap from a stream using a specific pixel configuration. If the image is too
 * large (ie causes an OutOfMemoryError situation) the method will iteratively try to
 * increase sample size up to a defined maximum sample size. The sample size will be doubled
 * each try since this it is recommended that the sample size should be a factor of two
 */
public Bitmap getAsBitmap(InputStream in, BitmapFactory.Config config, int maxDownsampling) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 1;   
    options.inPreferredConfig = config;
    Bitmap bitmap = null;
    // repeatedly try to the load the bitmap until successful or until max downsampling has been reached
    while(bitmap == null && options.inSampleSize <= maxDownsampling) {
        try {
            bitmap = BitmapFactory.decodeStream(in, null, options);
            if(bitmap == null) {
                // not sure if there's a point in continuing, might be better to exit early
                options.inSampleSize *= 2;
            }
        }
        catch(Exception e) {
            // exit early if we catch an exception, for instance an IOException
            break;
        }
        catch(OutOfMemoryError error) {
            // double the sample size, thus reducing the memory needed by 50%
            options.inSampleSize *= 2;
        }
    }
    return bitmap;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16679138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档