setDisplayOrientation示例代码是否正确? [英] Is the setDisplayOrientation sample code correct?

查看:300
本文介绍了setDisplayOrientation示例代码是否正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相机的文档页面。 setDisplayOrientation包含以下代码示例,说明使用它将使相机图像以与显示相同的方向显示:

The documentation page for Camera.setDisplayOrientation contains the following code sample stating that using it will "make the camera image show in the same orientation as the display":

 public static void setCameraDisplayOrientation(Activity activity,
         int cameraId, android.hardware.Camera camera) {
     android.hardware.Camera.CameraInfo info =
             new android.hardware.Camera.CameraInfo();
     android.hardware.Camera.getCameraInfo(cameraId, info);
     int rotation = activity.getWindowManager().getDefaultDisplay()
             .getRotation();
     int degrees = 0;
     switch (rotation) {
         case Surface.ROTATION_0: degrees = 0; break;
         case Surface.ROTATION_90: degrees = 90; break;
         case Surface.ROTATION_180: degrees = 180; break;
         case Surface.ROTATION_270: degrees = 270; break;
     }

     int result;
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
         result = (info.orientation + degrees) % 360;
         result = (360 - result) % 360;  // compensate the mirror
     } else {  // back-facing
         result = (info.orientation - degrees + 360) % 360;
     }
     camera.setDisplayOrientation(result);
 }

但是,我使用它有问题,有时图像会出现倒挂。经过一些尝试和错误,我发现正确的代码将(替换方法的最后8行):

However, I had problems using it, sometimes the image would appear upside down. After some trial-and-error, I found that the correct code would be (replacing the last 8 lines of the method):

    int result = (360 + info.orientation - degrees) % 360;
    camera.setDisplayOrientation(result);

(这意味着后置摄像头的计算也适用于前置摄像头)。镜子的评论是有点奇怪的,因为镜像不能被旋转撤消,那个操作只能交换90°和270°旋转,这对我来说真的没有意义。

(Which means the calculation for back-facing cameras is correct for front cameras too.) The "compensate the mirror" comment is a bit weird since mirroring cannot be undone by rotating, that operation only swaps 90° and 270° rotations which doesn't really make sense to me.

所以问题是:实际上是错误的,还是我缺少某些东西? 我尝试过多个设备,包括后台和前置摄像头以及所有支持的方向,所以我知道我的代码工作中。一个可能值得一提的细节:我的所有设备返回90°为 info.orientation

So the question is: is the sample wrong indeed or am I missing something? I tried it on multiple devices, both back and front cameras and all supported orientations, so I know that my code IS working. One little detail that might be worth mentioning: all my devices returned 90° as info.orientation.

编辑这里是我的相机代码,我已经在Nexus One和三星Galaxy S Plus。它用于我的头部跟踪3D应用,预览显示在左下角,并且应始终具有正确的方向。

Here is my camera-related code, I have tested it on a Nexus One and a Samsung Galaxy S Plus. It is used in my head-tracking 3D app, the preview is shown in the lower left corner and should always have the correct orientation.

解决方案(排序):它看起来像代码是正确的,但是我的测试手机(Samsung Galaxy S Plus)为前置摄像头的CameraInfo.orientation返回不正确的值。在这个模型上,有很多关于预览被显示出来的相关讨论(例子 here here )。一个修复方法是包含手动旋转图像的选项。

SOLUTION (sort of): It looks like the code is correct, but my testing phone (Samsung Galaxy S Plus) returns an incorrect value for the front camera's CameraInfo.orientation. There are many related discussions about the preview being shown upside down on this model (examples here and here). A way to fix is to include an option to manually rotate the image.

推荐答案

您引用的片段,我使用在我的项目中应用,在我的情况下没有问题。

The snippet you've quoted, which I used and applied in my project, is no problem in my circumstances.

对于我用于测试的所有设备(Galaxy Note,Galaxy S III,Galaxy Nexus,Galaxy Ace II,Nexus S),信息。方向全部返回270在前置摄像头,90在后置摄像头。

For all the devices (Galaxy Note, Galaxy S III, Galaxy Nexus, Galaxy Ace II, Nexus S) I used for test, info.Orientation all return 270 on front camera, and 90 on back camera.

经过几个讨论与问题提出者,我发现我误解了问题,所以我将答案分为两部分。

After a few discuss with the question raiser, I found I misunderstood the questions, so I divide the answer in two parts.

对于相机预览中的错误方向,请参阅此解决方案:

For the wrong orientation in camera preview, please refer to this solution:

首先请确保 info.Orientation 将返回270在前置摄像头上,90后置摄像头。
然后,请尝试将相机预览活动(或处理预览的类似类)设置为横向。

First please ensure info.Orientation will return 270 on front camera, 90 on back camera. Then please try set your camera preview activity (or similar class that handles the preview) orientation to landscape.

因此,当您浏览代码时,您将会找到:

Thus, when you go through the code, you'll find:

degree = 90 用于屏幕方向, info.Orientation = 270 为前置摄像头。那么你会得到 result =(270 - 90 + 360)%360 result = 180 ,这意味着将为您的前置摄像头视图旋转180度,以纠正前置摄像机倒置的问题。

degree = 90 for screen orientation, info.Orientation = 270 for the front camera. Then you'll get result = (270 - 90 + 360) % 360, result = 180, which means it will rotate clock wise 180 for your front camera view that will correct the front camera upside-down issue.

如果这个 info.Orientation 适用于您,那么问题可能是:

If this info.Orientation applies to you, then the problem may be:


  1. 对于一些三星(或其他)设备(如Galaxy Note,Galaxy SIII),相机只会写入方向标签,而不是旋转真实像素。

  2. 如果您正在使用前置摄像头并使用上述代码,则会以正确的方向显示预览,但如果您拍摄照片,则会显示倒置照片。

解决方案:

/**
 *
 * Get the orientation from EXIF
 * @param filepath
 * @return orientation
 */
public int getExifOrientation(String filepath) {
    int degree = 0;
    ExifInterface exif = null;
    try {
        exif = new ExifInterface(filepath);
    } catch (IOException ex) {
        Log.e("EXIF info", "cannot read exif", ex);
    }
    if (exif != null) {
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
        if (orientation != -1) {
            // We only recognize a subset of orientation tag values.
            switch(orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                degree = 90;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                degree = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                degree = 270;
                break;
            }
        }
    } else {
        degree = 1;
    }
    Log.i("EXIF info", "Orientation degrees: " + degree);
    return degree;
}

然后

if (isFromCamera) {

    if (fromFrontCam) {
        // try change here if the orientation still wrong, -90 means rotate counter-clockwise 90 degrees.
        matrix.preRotate(-90);
     } else {
        matrix.preRotate(90);
     }
} else {
    // read EXIF data
    getExifOrientation(path)
    // don't forget to handle the situation that some devices won't write exif data
    matrix.preRotate(degree);
}

这篇关于setDisplayOrientation示例代码是否正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆