没有渲染/虚拟内容的 ARKit/SceneKit 屏幕截图
Posted
技术标签:
【中文标题】没有渲染/虚拟内容的 ARKit/SceneKit 屏幕截图【英文标题】:ARKit/SceneKit Screenshot Without Rendered/Virtual Content 【发布时间】:2018-04-24 18:54:56 【问题描述】:我有一个非常简单的 ARKit 演示应用程序,我在其中放置了一些带有标签的对象。我目前正在使用ARSCNView
上的snapshot()
函数来获取视频输入的屏幕截图,其中包含我所有渲染的对象。
但是,我想获得一个仅包含原始相机输入的 UIImage,在此之上没有任何额外的渲染对象,最好与屏幕上显示的分辨率相同。我不确定最好的方法是什么。有没有办法剥离渲染的内容?我应该直接绑定到摄像头吗?
目前看起来有点像这样:
class ViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate
@IBOutlet weak var sceneView: ARSCNView!
var nodeModel:SCNNode!
...
override func viewDidLoad()
let scene = SCNScene()
sceneView.scene = scene
let modelScene = SCNScene(named: ...
nodeModel = modelScene?.rootNode.childNode(...
...
self.view.addSubview( ...
...some ARKit stuff...some model stuff...
extension ViewController
func renderer(_ renderer: SCNSceneRenderer, didRenderScene scene: SCNScene, atTime time: TimeInterval)
if self.captureButton.capturing && time > self.captureTime
captureScreenshot(scene)
self.captureTime = time + TimeInterval(0.1)
func captureScreenshot(_ scene: SCNScene)
DispatchQueue.main.async()
let screenshot = self.sceneView.snapshot()
UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
【问题讨论】:
【参考方案1】:实现可选的ARSessionDelegate
方法:
func session(_ session: ARSession, didUpdate frame: ARFrame)
ARFrame
有一个属性captureImage
,它是一个CVPixelBuffer
,然后您可以将其转换为UIImage
,如下所示:
import VideoToolbox
extension UIImage
public convenience init?(pixelBuffer: CVPixelBuffer)
var cgImage: CGImage?
VTCreateCGImageFromCVPixelBuffer(pixelBuffer, nil, &cgImage)
guard let cgImage = cgImage else return nil
self.init(cgImage: cgImage)
【讨论】:
不错的技巧,但请注意,您不一定需要委托方法来获取框架 - 您也可以从ARSession
获取 currentFrame
,然后您可以从视图中获取.
另请注意该 VideoToolbox 函数的文档中的这一点:源 CVPixelBuffer 可能会在 CGImage 的生命周期内保留。 持有相机系统提供的像素缓冲区是危险,因为相机会从池中回收缓冲区,如果您保留太多缓冲区太久,它将用完它可以使用的缓冲区,从而暂停捕获会话和您的ARSession
。如果您将该功能用于屏幕截图,请导出您的 PNG/JPEG/HEIF 图像数据,然后立即丢失 CGImage
。 (如果您想在 UI 中显示数据,请根据数据创建新图像。)
这实际上是我昨天找到的确切解决方案,我想我们甚至从同一个地方找到了 UIImage 扩展。 :)以上是关于没有渲染/虚拟内容的 ARKit/SceneKit 屏幕截图的主要内容,如果未能解决你的问题,请参考以下文章
ARKit + SceneKit:我可以访问帧的分段缓冲区但禁用自动人物遮挡吗?
将孩子添加到场景 ARKit/SceneKit 时 FPS 下降
Vue 警告客户端渲染的虚拟 DOM 树与服务器渲染的内容不匹配
Nuxt.js 错误:客户端渲染的虚拟 DOM 树与服务器渲染的内容不匹配
[Vue 警告]:客户端渲染的虚拟 DOM 树与服务器渲染的内容不匹配( Nuxt / Vue / lerna monorepo )