繁体   English   中英

设备相机方向,不包括设备横向/纵向

[英]Device camera direction excluding device landscape/portrait orientation

我需要获得不包括设备方向(横向/纵向)的前置摄像头的方向。 我尝试使用 Core Motion 和访问设备姿态来表示这一点。 在这里,我尝试访问欧拉角并排除偏航,但是当旋转设备超过一个欧拉角值变化时,这似乎不起作用。 我也在考虑使用方向四元数,但我没有使用它们的经验。 我需要以可序列化的方式获取此信息,因为我稍后需要确定其他设备的摄像头是否指向同一方向(该设备可能是 iOS 或 Android)。

重申:如果用户将他的手机摄像头(主摄像头不是自拍摄像头)指向自由女神像,那么无论用户是纵向还是横向拿着手机,编码此信息的最佳方式是什么,这样,如果另一个用户在同一位置他会知道指向他的相机的方向吗?

我相信为了实现这一点,您可以使用CLLocation 当你的主要目标是找到基点朝向手机点,你可以做这样的事情:

fun locationManager(_ manager: CLLocationManager, didUpdateHeading heading: CLHeading) {
   let angle = newHeading.trueHeading.toRadians // convert from degrees to radians
   // do what you please with this information
}

本教程所述

trueHeading 是该矢量与从同一点开始但指向真北的矢量之间的角度。 如果您的手机正好指向真北,您将获得 0(零)度的航向,如果它指向东方,您将获得 90 度等。

现在,正如此处所述,设备方向可能会导致一些麻烦:

不幸的是,如果用户将设备定向到横向模式,报告的标题将是不正确的,或者至少在用户看来是不正确的。 当您在本书后面查看增强现实界面时,这将变得尤为重要; 此类界面通常在横向左侧模式下查看。

但! 这个问题有一个解决方案:

你可以使用这样的东西来检索你正在寻找的标题:

-(float)magneticHeading:(float)heading 
        fromOrientation:(UIDeviceOrientation) orientation {

    float realHeading = heading;
    switch (orientation) {1
          case UIDeviceOrientationPortrait:
               break;
          case UIDeviceOrientationPortraitUpsideDown:
               realHeading = realHeading + 180.0f;
               break;
          case UIDeviceOrientationLandscapeLeft:
               realHeading = realHeading + 90.0f;
               break;
          case UIDeviceOrientationLandscapeRight:
               realHeading = realHeading - 90.0f;
               break;
          default:
               break;
    }
    while ( realHeading > 360.0f ) {
          realHeading = realHeading - 360;
    }
    return realHeading;
}

对不同的语言(Swift - Objective C)感到抱歉,但为了完全理解问题并找到完整的解决方案,我建议阅读源代码:

希望这可以帮助! 让我知道。

它们有 4 种类型。 一个被弃用:

  1. public static final int ORIENTATION_UNDEFINED = 0;
  2. public static final int ORIENTATION_PORTRAIT = 1;
  3. 公共静态最终 int ORIENTATION_LANDSCAPE = 2:
  4. @Deprecated public static final int ORIENTATION_SQUARE = 3;

你可以学习

val orientation: Int = resources.configuration.orientation

如果你想学习特定的角度和位置,你应该使用带有this.sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager传感器服务

和准确的位置

sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)?.let { this.rotationVector = it}

这个类也有不同的功能,比如。

TYPE_ACCELEROMETER

测量在所有三个物理轴(x、y 和 z)上施加到设备的加速力(以 m/s2 为单位),包括重力。

运动检测(摇晃、倾斜等)。

TYPE_GRAVITY

测量在所有三个物理轴(x、y、z)上施加到设备的重力(以 m/s2 为单位)。

运动检测(摇晃、倾斜等)。

TYPE_GYROSCOPE

测量设备绕三个物理轴(x、y 和 z)中的每一个轴的旋转速率(以 rad/s 为单位)。

旋转检测(旋转、转弯等)。

TYPE_LINEAR_ACCELERATION

以 m/s2 为单位测量在所有三个物理轴(x、y 和 z)上施加到设备的加速力,没有重力。

监测沿单轴的加速度。

TYPE_ROTATION_VECTOR

通过提供设备旋转矢量的三个元素来测量设备的方向。

运动检测和旋转检测。

在 android 中,我使用 setRotation() 方法来腐烂相机。

setRotation(camera, parameters, requestedCameraId);

private void setRotation(Camera camera, Camera.Parameters parameters, int cameraId) {
    WindowManager windowManager =
            (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    int degrees = 0;

    //get current display rotation
    int rotation = windowManager.getDefaultDisplay().getRotation();

    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;
        default:
            Log.e(TAG, "Bad rotation value: " + rotation);
    }

    CameraInfo cameraInfo = new CameraInfo();
    Camera.getCameraInfo(cameraId, cameraInfo);

    int angle;
    int displayAngle;
    if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
        angle = (cameraInfo.orientation + degrees) % 360;
        displayAngle = (360 - angle) % 360; // compensate for it being mirrored
    } else {  // back-facing
        angle = (cameraInfo.orientation - degrees + 360) % 360;
        displayAngle = angle;
    }

    // This corresponds to the rotation constants.
    // mRotation = angle / 90;

    camera.setDisplayOrientation(displayAngle);
    parameters.setRotation(angle);
}

我希望这对你有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM