3

在 Android 中,API 提供了视野角度:

  1. Camera.Parameters.getHorizontalViewAngle()
  2. Camera.Parameters.getVerticalViewAngle()

iOS中的等价物是什么? 我不想预先编写这些值,因为它不灵活。

4

2 回答 2

1

我不完全确定“水平”和“垂直”在这种情况下是什么意思,但我想到了两个计算,围绕“z”轴的旋转(即我们与照片中的地平线有多水平),以及如何它向前和向后倾斜(即围绕“x”轴旋转,即它是向上还是向下)。您可以使用Core Motion来做到这一点。只需将其添加到您的项目中,然后您就可以执行以下操作:

  1. 确保导入 CoreMotion 标头:

    #import <CoreMotion/CoreMotion.h>
    
  2. 定义一些类属性:

    @property (nonatomic, strong) CMMotionManager *motionManager;
    @property (nonatomic, strong) NSOperationQueue *deviceQueue;
    
  3. 启动运动管理器:

    - (void)startMotionManager
    {
        self.deviceQueue = [[NSOperationQueue alloc] init];
        self.motionManager = [[CMMotionManager alloc] init];
        self.motionManager.deviceMotionUpdateInterval = 5.0 / 60.0;
    
        [self.motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical
                                                                toQueue:self.deviceQueue
                                                            withHandler:^(CMDeviceMotion *motion, NSError *error)
        {
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                CGFloat x = motion.gravity.x;
                CGFloat y = motion.gravity.y;
                CGFloat z = motion.gravity.z;
    
                // how much is it rotated around the z axis
    
                CGFloat rotationAngle = atan2(y, x) + M_PI_2;                  // in radians
                CGFloat rotationAngleDegrees = rotationAngle * 180.0f / M_PI;  // in degrees
    
                // how far it it tilted forward and backward
    
                CGFloat r = sqrtf(x*x + y*y + z*z);
                CGFloat tiltAngle = (r == 0.0 ? 0.0 : acosf(z/r);              // in radians
                CGFloat tiltAngleDegrees = tiltAngle * 180.0f / M_PI - 90.0f); // in degrees
            }];
        }];
    }
    
  4. 完成后,停止运动管理器:

    - (void)stopMotionManager
    {
        [self.motionManager stopDeviceMotionUpdates];
        self.motionManager = nil;
        self.deviceQueue = nil;
    }
    

我没有对这里的值做任何事情,但您可以将它们保存在类属性中,然后您可以在应用程序的其他地方访问这些属性。或者您可以从这里将 UI 更新发送回主队列。一堆选项。

由于这是 iOS 5 及更高版本,如果应用程序支持早期版本,您可能还想弱链接 Core Motion 然后检查一切是否正常,如果没有,请意识到您不会捕获方向设备:

if ([CMMotionManager class]) 
{
    // ok, core motion exists
}

而且,如果您想知道我相当随意的选择每秒 12 次,在iOS 的事件处理指南中,如果只是检查设备的方向,他们建议 10-20/秒。

于 2013-05-15T02:25:55.890 回答
1

在 iOS 7.0+ 中,您可以通过读取该属性来获取相机的 FOV 角度。 https://developer.apple.com/documentation/avfoundation/avcapturedeviceformat/1624569-videofieldofview?language=objc

AVCaptureDevice *camera;
camera = ...
float fov = [[camera activeFormat] videoFieldOfView];
NSLog("FOV=%f(deg)", fov);
于 2018-11-09T15:40:47.830 回答