Android的CameraInfo.orientation是否正确记录?错误地实施了?

时间:2012-01-29 18:09:18

标签: android camera orientation

在Android中,您可以通过检索Camera来获取CameraInfo的属性说明。我对方向感兴趣,如http://developer.android.com/reference/android/hardware/Camera.CameraInfo.html#orientation

所述

然而,文档似乎与我的所有四个设备的行为方式不一致,并且,我有第五个设备的消息,这个设备似乎固定的值会发生变化。

特别是文档说:

  

该值是相机图像需要旋转的角度   顺时针方向,使其在显示屏上正确显示   取向。 ...例如,假设设备具有自然高度   屏幕。后置摄像头传感器安装在横向上。你是   看着屏幕。如果相机传感器的顶部对齐   屏幕右边缘自然定位,价值   应为90.如果前置摄像头传感器的顶部是   与屏幕右侧对齐,值应为270。

但在上述示例中,相机图像相对于自然高的方向顺时针旋转90度,而不是相反。也就是说,顶部与设备右侧对齐的图像需要顺时针旋转270度才能与设备的顶部对齐。

至少,我的所有四个设备都会为此值报告“90”,并且当自然方向保持时,所有设备的行为都好像设备的顶部是设备的右侧。也就是说,图像必须顺时针旋转270度,而不是90度,以匹配自然方向。这个例子似乎是对的;第一行没有。

This示例代码似乎支持我的结论,因为它只会在方向被解释为上面时给出正确的结果。

奇怪的是,我有来自一个用户设备的记录证据,表明它有时会报告此值为90,其他时间报告为0!它应该是相机在设备中的坐姿的物理属性,对吗?

  1. 任何人都可以确认文档的第一行实际上是错误的,示例是对的吗?
  2. 是否有人观察到CameraInfo.orientation的变化值?在文档中是否有证据表明这是合法行为,或者它可能是设备中的错误?
  3. 还有其他任何相关的评论,经历和陷阱吗?

3 个答案:

答案 0 :(得分:11)

我相信在经过一番思考之后,我已经回答了我自己的问题。

这个例子是正确的。而且,文本实际上是正确的。在给定的示例中,如果预览数据显示在屏幕上,它将显示为旋转90度计数器 - 时钟,因为数据中的“向上”位于显示器的右侧,并显示在显示器上,其“向上”是数据的左手可以这么说。因此,有必要通过在显示之前将图像数据顺时针旋转90度进行补偿。

我认为将这个数字理解为安装相机相对于自然方向的旋转更为自然。

出于这个原因和其他原因,我得出的结论是,显示方向变化值的设备只是错误的。至少,当它报告0时,其数据表现得像“90”是正确的值。

答案 1 :(得分:11)

  

1)任何人都可以确认文档的第一行是实际的   错了,这个例子是对的吗?

您已经在your answer内完全解决了这个问题,感谢您的后续解释!

  

2)是否有人观察到CameraInfo.orientation值的变化?在文档中是否有证据表明这是合法行为,或者是否可能是合法行为   设备中的错误?

虽然我可以很容易地想象这是一个原则上的错误,但由于结果信息通过照片中的EXIF嵌入(例如其他{{3}),它仍然会影响各种与成像相关的应用程序。暂时)。

因此,我认为它更有可能成为那些成千上万的Android设备之一的实际功能,即可以选择物理旋转镜头的相机。虽然我目前还不知道基于Android的手机,但过去常常有这样的手机,例如EXIF related bugs aside(~2004)或三星SCH-a930(~2006)(参见例如旋转相机镜头 LG VX7000),所以我不会感到惊讶这也会出现在Android领域。

顺便提一下,有一个未回答的问题为什么我的照片会在within the manual内对于后者进行颠倒或倒退。

  

最近我的照片一直颠倒或倒退。为什么是这样   发生了什么以及如何解决它。

这实际上可能是其他功能旋转调整硬件/固件中的错误;)

总而言之,我认为最好准备好能够改变的方向,直到你有更明确的证据证明这是一个有缺陷的设备。

答案 2 :(得分:0)

解决此问题的另一种方法是扩展OrientationEventListener 并覆盖方法onOrientationChanged即使自动旋转已禁用,您也将获得手机的方向(因为侦听器通过传感器发出旋转事件)。

你应该在onResume / onPause上启用和禁用方向监听器,以防止电池耗尽。

    private class OnOrientationChange extends OrientationEventListener {
    private boolean isEnabled = false;

    public OnOrientationChange(Context context) {
        super(context);
        disable();
    }

    @Override
    public void onOrientationChanged(int orientation) {
        if (camera != null && orientation != ORIENTATION_UNKNOWN) {
            int newOutputOrientation = getCameraPictureRotation(orientation);

            if (newOutputOrientation != outputOrientation) {
                outputOrientation = newOutputOrientation;

                Camera.Parameters params = camera.getParameters();

                params.setRotation(outputOrientation);

                try {
                    camera.setParameters(params);
                    lastPictureOrientation = outputOrientation;
                } catch (Exception e) {
                    Log.e(getClass().getSimpleName(),
                            "Exception updating camera parameters in orientation change",
                            e);
                    // TODO: get this info out to hosting app
                }
            }
        }
    }

    @Override
    public void enable() {
        isEnabled = true;
        super.enable();
    }

    @Override
    public void disable() {
        isEnabled = false;
        super.disable();
    }

    boolean isEnabled() {
        return (isEnabled);
    }
}

感谢解决方案的常用软件