2013-08-29 37 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客户端通常发送的任何数据)。