簡體   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