[英]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.