簡體   English   中英

如何使用浮點數而不是整數比例縮放位圖,而沒有OutOfMemory錯誤?

[英]How to scale a Bitmap with float instead of integer scales, without OutOfMemory Errors?

我正在嘗試調整可繪制對象的大小,使其縮放比例僅在極少數情況下可以存儲為整數。 目前,我正在使用此:

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)

我發現可以通過使用BitmapFactory而不是Bitmap解決此問題。 但是它的創建方法僅支持數據類型為整數的小數位數。 但是我需要秤為浮點數。

您對如何解決此問題有任何建議嗎?

位圖只是顏色值的數組,因此,位圖的字節大小是像素的“大小”(取決於位圖格式)乘以寬度和高度,該值必須是整數值:數組中的訪問元素始終是整數,不是嗎? 當然,數組的大小始終是整數。 這就是為什么您需要提供兩個整數才能創建位圖的原因。 您的第二次嘗試是正確的選擇,您只需要計算寬度和高度的值即可,例如它們保持在合理的較低水平。 據我所知,您的應用程序在嘗試分配10MB映像時崩潰了,實際上這是一個很大的映像。 如果您需要加載巨大的背景,也許您需要將其拆分成小塊,並在需要時一次加載一個圖塊。

完成釋放本地內存的操作后,請不要忘記調用Bitmap.recycle(),否則您的應用程序可能會崩潰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM