【问题标题】:Is there a way to display camera images without using AVCaptureVideoPreviewLayer?有没有办法在不使用 AVCaptureVideoPreviewLayer 的情况下显示相机图像?
【发布时间】:2018-03-23 05:20:54
【问题描述】:

有没有办法在不使用 AVCaptureVideoPreviewLayer 的情况下显示相机图像? 我想做截屏,但是我做不到。

    session = AVCaptureSession()

    camera = AVCaptureDevice.default(
        AVCaptureDevice.DeviceType.builtInWideAngleCamera,
        for: AVMediaType.video,
        position: .front) // position: .front
    do {
        input = try AVCaptureDeviceInput(device: camera)

    } catch let error as NSError {
        print(error)
    }

    if(session.canAddInput(input)) {
        session.addInput(input)
    }

    let previewLayer =  AVCaptureVideoPreviewLayer(session: session)
    cameraView.backgroundColor = UIColor.red
    previewLayer.frame = cameraView.bounds
    previewLayer.videoGravity = AVLayerVideoGravity.resizeAspect

    cameraview.layer.addSublayer(previewLayer)
    session.startRunning()

我目前正在尝试广播屏幕截图。就是合成摄像头图像和一些UIView。但是,如果您使用 AVCaptureVideoPreviewLayer 则无法完成屏幕捕获并且不会显示相机图像。因此,我想显示相机图像以便进行屏幕捕获。

【问题讨论】:

  • 是的,实际上有几种方法。但是你的目标到底是什么? “我想做屏幕截图,但我做不到”看起来很重要,所以最好重新表述整个事情并直接提出问题。请包括预期结果和您当前的结果。
  • @Matic Oblak 谢谢!我目前正在尝试播放屏幕截图。就是合成摄像头图像和一些UIView。但是,如果您使用 AVCaptureVideoPreviewLayer 则无法完成屏幕捕获并且不会显示相机图像。因此,我想显示相机图像,以便可以执行屏幕捕获。

标签: ios swift


【解决方案1】:

一般情况下,直接使用 GPU 显示的视图可能不会在 CPU 上重绘。这包括诸如 openGL 内容或这些预览层之类的情况。

“屏幕截图”在 CPU 上的新上下文中重绘屏幕,这显然忽略了 GPU 部分。

您应该尝试在会话中添加一些输出,这些输出将为您提供图像,或者更确切地说是CMSampleBuffer 可用于生成图像的镜头。

有很多方法可以做到这一点,但您很可能需要降低一步。您可以将输出添加到会话以直接接收样本。这样做有点代码,所以请参考其他一些帖子,如this one。这里的重点是您将拥有一个 didOutputSampleBuffer 方法,该方法将为您提供 CMSampleBufferRef 对象,这些对象可用于构建几乎任何图像方面的内容。

现在,在您的情况下,我假设您的目标是从样本缓冲区中获取 UIImage。为此,您可能再次需要一些代码,因此请参阅其他帖子,例如 this one

要将它们放在一起,您也可以简单地使用图像视图并删除预览层。当您获得样本缓冲区时,您可以创建图像并更新图像视图。我不确定这会是什么表现,但我不鼓励你这样做。如果图像本身足以满足您的情况,那么您根本不需要视图快照。

但如果你这样做:

在快照上创建此图像。然后用显示此生成图像的图像视图覆盖您的预览层(添加子视图)。然后创建快照并在单个块中删除图像视图:

func snapshot() -> UIImage? {
    let imageView = UIImageView(frame: self.previewPanelView.bounds)
    imageView.image = self.imageFromLatestSampleBuffer()
    imageView.contentMode = .aspectFill // Not sure
    self.previewPanelView.addSubview(imageView)

    let image = createSnapshot()

    imageView.removeFromSuperview()

    return image
}

让我们知道事情的进展和你的尝试,什么有效或无效。

【讨论】:

    猜你喜欢
    • 2019-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 2019-10-01
    • 2021-08-12
    相关资源
    最近更新 更多