4

我试图在 imageView 中旋转图像,并使用相同的图像旋转位图。

(我需要那个位图,因为我稍后将图像发送到服务器)

编码:

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

旋转()方法:

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);
    }

日志猫:

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)

希望你能帮助我。

泰!

4

5 回答 5

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

为了向用户显示图像,您需要先调整它的大小。关注关于如何有效加载和显示位图的著名开发人员文章。

但是在执行此操作时,您需要在计算宽度和高度参数时考虑旋转(我猜您正在使用Exif信息)。

将大图像发送到服务器很棘手。我看过这篇关于如何旋转大图像的帖子,但我没有时间尝试。这个想法是在另一个目标位图中旋转位图矩阵。

但是我建议在服务器端旋转图像,或者如果你不能在服务器端进行更改,因为它不属于你,创建你自己的代理服务器,将你的图像发送到该实例,在那里旋转它并从那里将旋转后的图像发送到初始服务器(通过转发 Android 客户端通常发送的任何数据)。

于 2013-08-29T20:41:45.600 回答
1

解码文件时试试这个

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文档:

公共 int inSampleSize

在 API 级别 1 中添加 如果设置的值 > 1,则请求解码器对原始图像进行二次采样,返回较小的图像以节省内存。样本大小是对应于解码位图中的单个像素的任一维度中的像素数。例如, inSampleSize == 4 返回的图像是原始宽度/高度的 1/4,像素数的 1/16。任何 <= 1 的值都被视为 1。注意:解码器使用基于 2 的幂的最终值,任何其他值将向下舍入到最接近的 2 幂。

希望这可以帮助

于 2013-08-29T20:31:05.047 回答
0

在您开始优化之前,我会确保您在实际目标设备上的内存不足,而不仅仅是在模拟器中。如果它在设备本身上运行良好,请检查您的 VM 场景中的 heapSize。您还可以通过 Manifest 请求设备上的更多内存,方法是在标签中设置 android:largeHeap="true"。如果在执行这些步骤之后,您仍然遇到设备限制,是的,您需要进行优化。

对于某些设备上如此大的位图而言,图像处理可能过于繁琐。我注意到您正计划将其发送到服务器。然后我可以假设您希望图像正确旋转以显示服务器端吗?如果是这种情况,如果你使用 Python,你总是可以在那里进行图像处理,例如使用 PIL。只是一个想法。

祝你好运。

于 2013-08-29T20:38:44.883 回答
0

与其在每次旋转时分配一个大小为 2560 x 1920 的新位图,不如在与ImageView相同的范围内保存对android.graphics.Matrix的引用并使用?image.setScaleType(ScaleType.MATRIX); image.setImageMatrix(matrix);

您的旋转方法可能如下所示:

if (mMatrix == null) {
    mMatrix = new Matrix();
}
mMatrix.postRotate(degrees);
mImageView.setImageMatrix(mMatrix);
于 2013-08-29T20:36:49.063 回答
0

请看一下这个相关的问题,也发布在 SO

看起来recycle()应该对旋转的位图进行一些调用,因此分配在其上的内存被释放,假设不会使用旧的未旋转版本的位图。

另请查看Bitmap 类文档

于 2013-08-29T20:31:59.457 回答