我按照以下说明裁剪图像。
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 :(得分:14)
您可以使用可以解决问题的以下代码来使用裁剪图像。
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 :(得分:8)
我的同事只是让我熟悉这个Android API ...请参阅ThumbnailUtils。
它会为您调整大小和裁剪。
答案 2 :(得分:2)
如果您的代码与示例不同,则必须将其发布以获得准确的帮助。否则,仅基于日志 - 这是一个答案:
在您使用的示例中,开发人员正在将应用程序资源文件夹(可能相对较小的图像)裁剪为300x300位图图像。首先,尝试在您自己的应用中裁剪较小尺寸的图像,缩小输出尺寸,以查看代码是否存在问题,或者您使用的图像对于您的代码或设备来说太大了。
由于您说的是裁剪的最终图像比屏幕大,这可能是问题所在,并且您遇到了在Android中使用位图的基本挑战。位图文件大小是像素宽度乘以高度的函数 - 它们变得更快。
您可以通过Google搜索日志的其他部分来解决,例如“位图大小超过VM预算”,您将在stackoverflow上找到几个有用的线程,就像这个一样。
Strange out of memory issue while loading an image to a Bitmap object
您可以使用位图选项和inSampleSize以及其他技术来解决它。
答案 3 :(得分:1)
查看类似的讨论here
,它们似乎有同样的byte external allocation too large for this process
错误。
答案 4 :(得分:1)
我进一步验证了以下说明。
http://coderzheaven.com/index.php/2011/03/crop-an-image-in-android/
我发现代码不够好,有些代码是多余的。
要裁剪大位图图像,不需要使用矩阵来完成任务。
只需使用canvas.drawBitmap方法即可裁剪大图片!
也无需触摸BitmapFactory.Options。
现在我简单地裁剪图像并让imageview调整大小。没有更多的内存不足错误。答对了 !
答案 5 :(得分:1)
04-09 11:37:28.708:ERROR / AndroidRuntime(4003):at com.test.Test.onCreate(Test.java:57)
如果我没记错的话,
class Test extends Activity ....
第57行,你有
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),R.drawable.image);
如果是这样,引用的图像是如此之大,以至于当Android尝试将其解码为位图时,它会占用所有空闲的VM堆并抛出错误。您无法使用
解码大位图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中找到“比例类型”选项,在hete中找到setScaleType详细信息。
希望这有帮助。
我还建议不要在资源上有这么重的照片。在将它们保存在resorce forder中之前,先将它们缩小。
答案 6 :(得分: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);
答案 7 :(得分: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);
我希望有用