2011-04-09 202 views
2

我按照下面的說明裁剪圖像。Android中的圖像裁剪和調整大小

http://coderzheaven.com/index.php/2011/03/crop-an-image-in-android/

的高度和最終的寬度裁切位圖圖像均大於屏幕的尺寸。

在調整大小和作物進程,內存不足的錯誤被拋出和應用程序被強制退出。

錯誤日誌:

04-09 11:37:28.658: ERROR/dalvikvm-heap(4003): 435176-byte external allocation too large for this process. 
04-09 11:37:28.658: ERROR/GraphicsJNI(4003): VM won't let us allocate 435176 bytes  
04-09 11:37:28.668: WARN/dalvikvm(4003): threadid=1: thread exiting with uncaught exception (group=0x4001d800)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): FATAL EXCEPTION: main  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): java.lang.OutOfMemoryError: bitmap size exceeds VM budget  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at android.graphics.Bitmap.nativeCreate(Native Method)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at android.graphics.Bitmap.createBitmap(Bitmap.java:468)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at android.graphics.Bitmap.createBitmap(Bitmap.java:435)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at com.test.Test.onCreate(Test.java:57)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at android.app.ActivityThread.access$2300(ActivityThread.java:125)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at android.os.Handler.dispatchMessage(Handler.java:99) 
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at android.os.Looper.loop(Looper.java:123)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at android.app.ActivityThread.main(ActivityThread.java:4627)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at java.lang.reflect.Method.invokeNative(Native Method)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at java.lang.reflect.Method.invoke(Method.java:521)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)  
04-09 11:37:28.708: ERROR/AndroidRuntime(4003): at dalvik.system.NativeStart.main(Native Method) 

有誰知道如何解決這個問題?

謝謝。

======

更新:我解決了這個問題。

+0

發佈錯誤,顯示一些代碼!如果我們不知道問題是什麼,我們應該如何幫助! – user432209 2011-04-09 02:15:41

+0

錯誤是應用程序被迫退出。 – user403015 2011-04-09 02:49:44

+0

運行'adb logcat AndroidRuntime:* *:S'來獲取崩潰日誌。用你的代碼發佈,我們可以提供幫助。 – Chase 2011-04-09 03:04:25

回答

2

如果您的代碼與示例有所不同,您必須將其發佈以獲得確切的幫助。否則,僅基於日誌 - 這裏是一個答案:

在您使用的示例中,開發人員正在將應用程序的資源文件夾中的圖像(可能相對較小以開始)裁剪爲300x300位圖圖像。首先,嘗試在自己的應用中裁剪較小尺寸的圖像,以縮小輸出尺寸,查看代碼是否存在問題,或者如果您使用的圖像對於代碼或設備來說太大。

既然你說你是裁剪最終圖像更大的屏幕,這可能是問題,和您遇到在使用Android的位圖的基本挑戰。位圖文件大小是像素寬度乘高度的函數 - 它們變得更快。

您可以通過谷歌搜索日誌的其他部分,如解決「位圖大小超過VM預算」,你會發現計算器上的多個線程,將幫助,像這樣的。

Strange out of memory issue while loading an image to a Bitmap object

您可以通過使用位圖選項和inSampleSize,以及其他技術解決這個問題。

1

看那類似的討論here,他們似乎具有相同byte external allocation too large for this process錯誤。

1

我進一步驗證了以下說明。

http://coderzheaven.com/index.php/2011/03/crop-an-image-in-android/

我發現,這些代碼都不夠好,其中一些是多餘的。

要裁剪大的位圖圖像,不需要使用矩陣來完成任務。

只要使用canvas.drawBitmap方法可以裁剪大圖像!

也無需觸摸BitmapFactory.Options。

現在我只是裁剪圖像,讓imageview調整它。沒有更多的內存不足錯誤。答對了 !

1

11月4日至9日:37:28.708:ERROR/AndroidRuntime(4003):在com.test.Test.onCreate(Test.java:57)

如果我沒有錯,在

上線57
class Test extends Activity .... 

,你有

Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),R.drawable.image); 

如果是這樣,則引用的圖像是如此之大,當Android的嘗試將其解碼成位圖,它cosumes所有的自由VM堆,並拋出theerror。你不能用

private Bitmap decodeFile(){ 
    try { 
     //Decode image size 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeResource(getResources(),R.drawable.image,o); 

     //The new size we want to scale to 
     final int REQUIRED_SIZE=100; 

     //Find the correct scale value. It should be the power of 2. 
     int width_tmp=o.outWidth, height_tmp=o.outHeight; 
     int scale=1; 
     while(true){ 
      if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) 
       break; 
      width_tmp/=2; 
      height_tmp/=2; 
      scale*=2; 
     } 

     //Decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize=scale; 
     return BitmapFactory.decodeResource(getResources(),R.drawable.image, o2); 
    } catch (FileNotFoundException e) {} 
    return null; 
} 

我從user699618建議鏈接複製的代碼進行解碼大位圖,我已經使用過它,它解決了這個問題)。

之後,你可以只使用CENTER_CROP或任何你需要的ImageView.setScaleType()

您可以在here中找到Scale Type選項,並在hete中找到setScaleType的詳細信息。

希望這會有所幫助。

我也建議不要在資源中擁有如此沉重的圖片。在將它們保存在resorce forder中之前使它們變小。

12

您可以使用裁剪圖像使用下面的代碼,可以解決您的問題。

Matrix matrix = new Matrix(); 
matrix.postScale(0.5f, 0.5f); 
Bitmap croppedBitmap = Bitmap.createBitmap(bitmapOriginal, 100, 100,100, 100, matrix, true); 

以上方法在修剪前做postScalling形象,這樣你就可以裁剪圖像獲得最好的結果沒有得到OOM錯誤。

更多的細節可以參考this blog

+1

最好的答案,謝謝@Hitesh。注意在某些情況下,這是令人難以置信的簡單和可靠的解決方案:http://stackoverflow.com/a/17733530/294884 – Fattie 2014-05-26 08:39:53

1
//solution for bit map resizing 
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight,Bitmap.Config.ARGB_8888); 

RectF rectf = new RectF(0, 0, 800, 400); 

Canvas canvas = new Canvas(targetBitmap); 
Path path = new Path(); 

path.addRect(rectf, Path.Direction.CW); 
canvas.clipPath(path); 
int xaxis=bm.getWidth(); 
int yaxis=bm.getHeight(); 
canvas.drawBitmap(bm, new Rect(0, 0, bm.getWidth(), bm.getHeight()), 
         new Rect(0, 0, targetWidth, targetHeight), paint); 
Matrix matrix = new Matrix(); 
matrix.postScale(1f, 1f); 
resizedBitmap = Bitmap.createBitmap(targetBitmap, 0, 0, width, height, matrix, true); 

BitmapDrawable bd = new BitmapDrawable(resizedBitmap); 
0
//get screen resolution; 
    WindowManager display = getWindowManager(); 
    Point size = new Point(); 
    display.getDefaultDisplay().getSize(size);  
    int width = size.x; 
    int height = size.y; 
    // scale the bitmap according to the screen resolution . 
    Bitmap bMap = BitmapFactory.decodeResource(getResources(), .drawable.ima1); 
    bMap = Bitmap.createScaledBitmap(bMap, width, height, true); 
    // then crop under value of the screen size and bitmap! 
    bMap = Bitmap.createBitmap(bMap, 0, 0, width/2, height); 
    Drawable drawa = new BitmapDrawable(getResources(),bMap); 

我希望能成爲有用的