1

VSD220 で OutOfMemoryError が発生しました (これは 22 インチの Android ベースのオールインワンです)。

for (ImageView img : listImages) {
            System.gc();

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

この画像は最大解像度を下回っているため、どうすればよいかわかりません。画像サイズは約 (1000x1000) で、ディスプレイは 1920x1080 です。

何か助けはありますか?(その foreach サイクルは約 20 要素用であり、6 回または 7 回のループ後に壊れてしまいます..)

どうもありがとう。

エゼキエル。

4

2 に答える 2

1

Managing Bitmap Memoryのトレーニング ドキュメントを参照してください。OS のバージョンによっては、さまざまな手法を使用してより多くのビットマップを管理できるようにすることもできますが、おそらくコードを変更する必要があります。

特に、「縮小版をメモリにロードする」の修正版のコードを使用する必要があるかもしれませんが、少なくともこのセクションが特に役立つことがわかりました。

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 に任意のサイズのビットマップを簡単に読み込むことができます。

mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
于 2013-05-21T22:22:28.870 に答える
0

同じビットマップを 20 回ロードしてもよろしいですか? 一度ロードしてループ内に設定したくありませんか。

それでも、画面の解像度に関係なく、1000x1000 ピクセルの画像の読み込みは保証されていません。1000x1000 ピクセルの画像は 1000x1000x4 バイト = ~4MB (ARGB_8888 としてロードした場合) を占めることに注意してください。ヒープ メモリが断片化している/小さすぎる場合は、ビットマップを読み込むのに十分なスペースがない可能性があります。BitmapFactory.Optionsクラスを調べて、inPreferredConfiginSampleSizeを試してください。

DigCamara による提案を使用してサイズを決定し、ほぼそのサイズのダウンサンプリングされた画像をロードすることをお勧めします (そのテクニックを使用しても正確なサイズが得られないため、ほぼと言います)。画像のサイズを変更し、最大サンプル サイズに達するか、画像が読み込まれるまで、再帰的にサンプル サイズを増やします (最良の結果を得るには 2 倍にします)。

/**
 * 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;
}
于 2013-05-21T21:58:57.450 に答える