2013-08-29 31 views
4

我試圖旋轉圖像內的圖像,也用相同的圖像旋轉位圖。OutOfMemory錯誤當試圖旋轉圖像內的圖像

(我需要該位圖,因爲林發送圖像到服務器後)

的代碼:

image.setOnClickListener(new OnClickListener() { 
    public void onClick(View view) { 
     mPhoto=rotate(mPhoto,90); 
     image.setImageBitmap(mPhoto); 
    } 
}); 

rotate()方法:

public static Bitmap rotate(Bitmap src, float degree) { 
     // create new matrix 
     Matrix matrix = new Matrix(); 
     // setup rotation degree 
     matrix.postRotate(degree); 
     // return new bitmap rotated using matrix 
     return Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true); 
    } 

logcat的:

08-29 23:14:34.964: W/dalvikvm(20087): threadid=1: thread exiting with uncaught exception (group=0x41505930) 
08-29 23:14:34.968: E/AndroidRuntime(20087): FATAL EXCEPTION: main 
08-29 23:14:34.968: E/AndroidRuntime(20087): java.lang.OutOfMemoryError 
08-29 23:14:34.968: E/AndroidRuntime(20087): at android.graphics.Bitmap.nativeCreate(Native Method) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at android.graphics.Bitmap.createBitmap(Bitmap.java:689) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at android.graphics.Bitmap.createBitmap(Bitmap.java:666) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at android.graphics.Bitmap.createBitmap(Bitmap.java:599) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at com.example.free.Add.rotate(Add.java:356) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at com.example.free.Add$5.onClick(Add.java:137) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at android.view.View.performClick(View.java:4211) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at android.view.View$PerformClick.run(View.java:17362) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at android.os.Handler.handleCallback(Handler.java:725) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at android.os.Handler.dispatchMessage(Handler.java:92) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at android.os.Looper.loop(Looper.java:137) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at android.app.ActivityThread.main(ActivityThread.java:5227) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at java.lang.reflect.Method.invokeNative(Native Method) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at java.lang.reflect.Method.invoke(Method.java:511) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562) 
08-29 23:14:34.968: E/AndroidRuntime(20087): at dalvik.system.NativeStart.main(Native Method) 

Hope y你可以幫助我。

Ty!

+0

你的形象有多大? – Fraggle

+0

不能發送圖像原樣並在服務器端旋轉(如果服務器是你的)?發送一個參數來表示。 – gunar

+0

2560X1920。它的大,但我必須找到一種方法來適應它.. @gunar - 我必須先顯示此圖像給用戶,然後再發送到服務器。 – NirPes

回答

0

試試這個,當你解碼文件

File imgFile = new File("yourPath"); 
BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inSampleSize = 10; 
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath(), options); 

然後調用

rotate(myBitmap,90); 

BitmapFactory.Options文檔:

公衆詮釋inSampleSize

在API級別1 如果設置爲大於1的值,請求解碼器對原始圖像進行二次採樣,返回較小的圖像以節省存儲空間。樣本大小是任一維度中與解碼位圖中的單個像素對應的像素數量。例如,inSampleSize == 4返回的圖像是原始寬度/高度的1/4,以及像素數量的1/16。任何值< = 1同等對待。注意:所述解碼器使用基於2的冪的最終值,任何其它值將被向下舍入至2

希望的最近的電源這有助於

0

請看看this related issue,還張貼在SO

看起來有些recycle()調用應在旋轉後的位進行,這樣就可以分配的內存被釋放的時候,假設位圖的舊非旋轉的版本不會用過的。

而且看一看的Bitmap class documentation

0

而不是分配大小每次旋轉時2560×1920的一個新的位圖,爲什麼在同樣的範圍不抱到android.graphics.Matrix的引用作爲您的ImageView和使用image.setScaleType(ScaleType.MATRIX); image.setImageMatrix(matrix);

你的旋轉方法可能如下所示:

if (mMatrix == null) { 
    mMatrix = new Matrix(); 
} 
mMatrix.postRotate(degrees); 
mImageView.setImageMatrix(mMatrix); 
0

你開始優化之前,我會確保你在實際的目標設備運行內存,而不是簡單地在模擬器。如果它在設備本身上運行良好,請檢查VM場景中的heapSize。您還可以通過在標籤中設置android:largeHeap =「true」,通過Manifest在設備上請求更多內存。如果在遵循這些步驟之後仍然遇到設備限制,那麼您需要進行優化。

這可能是圖像處理對某些設備上的如此大的位圖太簡單了。我注意到你打算把這個發送到服務器。那麼我可以假設你想讓圖像爲顯示服務器端正確旋轉?如果是這樣的話,你可以隨時在那裏做圖像處理,例如用PIL,如果你使用的是Python。只是一個想法。

祝你好運。

1

考慮到你的意見:2560X1920. Its big, but I have to find a way to fit it in.. @gunar - I have to show this image to the user before sending it to the server

爲了向用戶顯示圖像,您需要先調整圖像大小。關於如何有效地加載&顯示位圖,請按照the famous developer article

但是當這樣做時,在計算寬度和高度的參數時我需要考慮旋轉(我想你使用的是Exif信息)。

發送大圖像到服務器是棘手的。我看過this post關於如何旋轉大圖像,但我沒有時間去嘗試。這個想法是旋轉另一個目標位圖中的位圖矩陣。

但是我會建議旋轉服務器端的圖像,或者如果您不能在服務器端進行更改,因爲它不屬於您,請創建自己的代理服務器,將圖像發送到該實例,在那裏旋轉它並從那裏發送旋轉後的圖像到初始服務器(通過轉發Android客戶端通常發送的任何數據)。