1

多くの画像をスプライトとして構成する Android ゲームを開発しています。

次の方法で画像をロードすると:

public static Bitmap loadBitmap(int resId) {  
    return BitmapFactory.decodeResource(getResources(), resId, options);
}

すべてが完全に正常に動作します。

このコードでビットマップを縮小または拡大しようとすると:

public static Bitmap loadBitmap(int resId) {
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId, options);
    Matrix matrix = new Matrix();
    matrix.postScale(0.8f, 0.8f);
    Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    bitmap.recycle();
    bitmap = null;
    return scaledBitmap;
}

次の例外でアプリケーションがクラッシュします。

2211840-byte external allocation too large for this process.  
Out of memory: Heap Size=4935KB, Allocated=2549KB, Bitmap Size=18463KB  
VM won't let us allocate 2211840 bytes

スケーリングによって OutOfMemory 例外が発生するのはなぜですか? スペースを節約するために、元の画像をリサイクルしようとさえしています。Bitmap.createScaledBitmap(...)このメソッドは内部でメモリ リークを行うため (他のオンライン リソースで説明されているように)、意図的に使用しているわけではありません。

前もってありがとう、
ズラトコ

4

3 に答える 3

1

おそらく、メモリの制限に非常に近づいています。かなり大きなビットマップを作成しているようです (元のビットマップと同じサイズにする理由がわかりません)。ログから、25MB の Java 割り当てと 18MB のビットマップ割り当てを使用しているため、基本的に 48MB のヒープ制限に達しています。

また、createScaledBitmap() がリークする可能性は非常に低いと思います。それがすることは基本的にあなたがここでしていることだけです。

于 2011-05-28T00:39:19.923 に答える
0

あなたは本当にヒープ制限に近づいていると思います。あなたの関数では、基本的に2番目のビットマップをインスタンス化しています。これはおおよそメモリを2倍にすることになります(ビットマップは非常に大きいです)。Honeycombより前のOSを使用している場合は、どこかに出力されているメモリ値を確認することも誤解を招きます。iirc、ビットマップはシステムメモリヒープに直接保持されますが、他のすべてはvmヒープに保持されます(これらは表示される値です-> 2.5MB)。ただし、ビットマップ割り当て用のメモリは、メモリヒープ制限にもカウントされます。:/

このGoogleI/ Oセッションをご覧になることをお勧めします:http ://www.youtube.com/watch?v = _CruQY55HOk

あなたの問題は、ビットマップの解像度を下げるか、新しいビットマップをインスタンス化せず、既存のビットマップを変更しないスケール関数を使用することによってのみ解決できると思います(AmandeepGrewalによって言及されたもののように)。

于 2011-05-28T02:30:36.977 に答える
0

BitmapFactory.Options クラスで変数「inSampleSized」を使用するようにしてください。これにより、余分なメモリを使用せずにスケーリングされます。

http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize

于 2011-05-28T02:03:08.473 に答える