0

ドローアブルのサイズを変更しようとしていますが、まれに整数として格納できる値であるスケールを使用しています。現在、私はこれを使用しています:

private BitmapDrawable getCustomMarker(float scale){
    Bitmap originalMarker = BitmapFactory.decodeResource(this.getResources(), R.drawable.zone);
    int width = originalMarker.getWidth();
    int height = originalMarker.getHeight();

    Matrix matrix = new Matrix();
    matrix.postScale(scale, scale);

    Bitmap bitmap = Bitmap.createBitmap(originalMarker, 0, 0, width, height, matrix, true);


    BitmapDrawable bm = new BitmapDrawable(bitmap);
    bm.setBounds(0,0,bitmap.getWidth(),bitmap.getHeight());
    return bm;  
}

しかし、時々 OutOfMemoryError がスローされます....スケールを 1 より大きいものに変更したい場合もありますが、1 より小さいものにスケールダウンしたい場合もあります。

06-22 13:51:41.700: E/dalvikvm-heap(15021): Out of memory on a 10035216-byte allocation.
06-22 13:51:41.700: I/dalvikvm(15021): "main" prio=5 tid=1 RUNNABLE
06-22 13:51:41.700: I/dalvikvm(15021):   | group="main" sCount=0 dsCount=0 obj=0x401c75a8 self=0x12690
06-22 13:51:41.700: I/dalvikvm(15021):   | sysTid=15021 nice=0 sched=0/0 cgrp=default handle=-1342909336
06-22 13:51:41.700: I/dalvikvm(15021):   | schedstat=( 12261804000 820393000 4881 ) utm=1121 stm=105 core=0
06-22 13:51:41.700: I/dalvikvm(15021):   at android.graphics.Bitmap.nativeCreate(Native Method)
06-22 13:51:41.700: I/dalvikvm(15021):   at android.graphics.Bitmap.createBitmap(Bitmap.java:604)
06-22 13:51:41.700: I/dalvikvm(15021):   at android.graphics.Bitmap.createBitmap(Bitmap.java:551)
06-22 13:51:41.700: I/dalvikvm(15021):   at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437)
06-22 13:51:41.700: I/dalvikvm(15021):   at m.p.Activitys.GeoFancingActivity.getCustomMarker(GeoFancingActivity.java:61)
06-22 13:51:41.700: I/dalvikvm(15021):   at m.p.Activitys.GeoFancingActivity.adjustFanceScale(GeoFancingActivity.java:254)
06-22 13:51:41.700: I/dalvikvm(15021):   at m.p.Activitys.GeoFancingActivity.dispatchTouchEvent(GeoFancingActivity.java:194)
06-22 13:51:41.700: I/dalvikvm(15021):   at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1835)
06-22 13:51:41.700: I/dalvikvm(15021):   at android.view.View.dispatchPointerEvent(View.java:4694)
06-22 13:51:41.700: I/dalvikvm(15021):   at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2419)
06-22 13:51:41.700: I/dalvikvm(15021):   at android.view.ViewRoot.handleMessage(ViewRoot.java:2080)
06-22 13:51:41.700: I/dalvikvm(15021):   at android.os.Handler.dispatchMessage(Handler.java:99)
06-22 13:51:41.700: I/dalvikvm(15021):   at android.os.Looper.loop(Looper.java:132)
06-22 13:51:41.700: I/dalvikvm(15021):   at android.app.ActivityThread.main(ActivityThread.java:4126)
06-22 13:51:41.700: I/dalvikvm(15021):   at java.lang.reflect.Method.invokeNative(Native Method)
06-22 13:51:41.700: I/dalvikvm(15021):   at java.lang.reflect.Method.invoke(Method.java:491)
06-22 13:51:41.700: I/dalvikvm(15021):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
06-22 13:51:41.700: I/dalvikvm(15021):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
06-22 13:51:41.700: I/dalvikvm(15021):   at dalvik.system.NativeStart.main(Native Method)
06-22 13:51:41.700: D/AndroidRuntime(15021): Shutting down VM
06-22 13:51:41.700: W/dalvikvm(15021): threadid=1: thread exiting with uncaught exception (group=0x401c0760)
06-22 13:51:41.700: E/AndroidRuntime(15021): FATAL EXCEPTION: main
06-22 13:51:41.700: E/AndroidRuntime(15021): java.lang.OutOfMemoryError
06-22 13:51:41.700: E/AndroidRuntime(15021):    at android.graphics.Bitmap.nativeCreate(Native Method)
06-22 13:51:41.700: E/AndroidRuntime(15021):    at android.graphics.Bitmap.createBitmap(Bitmap.java:604)
06-22 13:51:41.700: E/AndroidRuntime(15021):    at android.graphics.Bitmap.createBitmap(Bitmap.java:551)
06-22 13:51:41.700: E/AndroidRuntime(15021):    at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437)
06-22 13:51:41.700: E/AndroidRuntime(15021):    at m.p.Activitys.GeoFancingActivity.getCustomMarker(GeoFancingActivity.java:61)
06-22 13:51:41.700: E/AndroidRuntime(15021):    at m.p.Activitys.GeoFancingActivity.adjustFanceScale(GeoFancingActivity.java:254)
06-22 13:51:41.700: E/AndroidRuntime(15021):    at m.p.Activitys.GeoFancingActivity.dispatchTouchEvent(GeoFancingActivity.java:194)
06-22 13:51:41.700: E/AndroidRuntime(15021):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1835)
06-22 13:51:41.700: E/AndroidRuntime(15021):    at android.view.View.dispatchPointerEvent(View.java:4694)
06-22 13:51:41.700: E/AndroidRuntime(15021):    at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2419)
06-22 13:51:41.700: E/AndroidRuntime(15021):    at android.view.ViewRoot.handleMessage(ViewRoot.java:2080)

Bitmap.createScaledBitmap() も使用しようとしましたが、このエラーも発生します。

Bitmap.createScaledBitmap(originalMarker, Math.round(originalMarker.getWidth() * scale), Math.round(originalMarker.getHeight() * scale), true)

Bitmap の代わりにBitmapFactoryを使用することで、この問題を解決できることがわかりました。ただし、その作成方法は、データ型が整数のスケールのみをサポートします。しかし、フロートとしてスケールが必要です。

この問題を解決する方法について何か提案はありますか?

4

1 に答える 1

1

ビットマップは単に色の値の配列であるため、ビットマップのバイト単位のサイズは、ピクセルの「サイズ」(ビットマップ形式によって異なります)に幅と高さを掛けたものであり、整数値である必要があります。配列内のアクセス要素は常に整数ですよね?もちろん、配列のサイズは常に整数です。そのため、ビットマップを作成するには2つの整数を指定する必要があります。2番目の試みは正しい選択です。適度に低いままであるように、幅と高さの値を計算するだけで済みます。私の知る限り、10 MBの画像を割り当てようとしてアプリがクラッシュしましたが、これは実際には非常に大きな画像です。巨大な背景をロードする必要がある場合は、それを小さなチャンクに分割し、必要なときに一度にタイルをロードする必要があるかもしれません。

ネイティブメモリの解放が完了したら、Bitmap.recycle()を呼び出すことを忘れないでください。そうしないと、アプリがクラッシュする可能性があります。

于 2012-06-22T12:48:36.810 に答える