2011-04-09 115 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); 

我希望能成为有用的