[英]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 種類型。 一個被棄用:
你可以學習
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.