ARView 是一个集成度非常高的控件,我们可以直接使用 ARView 来创建一个可预览的视频界面。这篇文章介绍的是如何在 ARView 上实现画面的缩放。
ARView 的 Camera 管理是由 ARSession 来进行的 (arview.session
),目前我并未找到能够通过 ARSession
获取其内部的 Camera 相关的对象的方法。值得另辟蹊径。根据我的理解,Camera 相关的对象是对设备的直接抽象,所以这类对象应该是 Singleton 模式的,即如果我通过其他渠道获取到 Camera 对象,那么这个对象和 ARView 使用的 Camera 对象应该是同一个。
使用下面的代码获取默认的摄像头对象
1 | let device = AVCaptureDevice.default(for: .video) |
使用 AVCaptureDevice.videoZoomFactor
可以缩放画面。例如下面我写了一个 Pinch 操作的响应函数:
1 | @objc |
这个函数可以实现对通过双指捏合操作对摄像头画面进行缩放,且可以直接影响到 ARView 的画面。
但是在成功地实现 ARView 的画面缩放之后,我发现了两个问题:
- Xcode 的 Console 中会输出大量的警告信息,显示摄像头的校准矩阵出现问题;
- 放大的画面比较粗糙
这两个现象的原因,经过我的分析是:ARKit 的 SLAM 追踪算法同摄像头参数高度耦合的,其内部模型无法适应画面的缩放。如画面如果放大到 x2,那么手机转动同样的角度,同样距离的物体相对运动的像素数量是不同的。也是出于同样的原因,ARSession 配置的摄像头是固定的,其videoZoomFactorUpscaleThreshold
几乎是1。这意味着摄像头完全不能进行光学放大,我们在设置videoZoomFactor
时,实质上底层只是将摄像头的内容进行scale+crop操作。