【问题标题】:How to show a AVCaptureVideoPreviewLayer in SwiftUI如何在 SwiftUI 中显示 AVCaptureVideoPreviewLayer
【发布时间】:2019-12-24 02:12:37
【问题描述】:

在以前版本的 swift 中,您在 ViewController 中创建一个 AVCaptureVideoPreviewLayer 并使用 view.layer.addSublayer(previewLayer) 将其添加到默认视图中。

这是如何在 SwiftUI ContentView 中完成的? SwiftUI 中的所有视图类型似乎都没有 addSublayer。没有 Text("Hello World").layer.addSublayer....

我尝试将 previewLayer 添加到 ContentView 中的各种视图

import Foundation
import AVFoundation
import Combine
import SwiftUI

class Scanner: NSObject, AVCaptureMetadataOutputObjectsDelegate, ObservableObject {

    @Published var captureSession: AVCaptureSession!
    @Published var previewLayer: AVCaptureVideoPreviewLayer!
    @Published var previewView: UIView

    override init() {

        captureSession = AVCaptureSession()
        previewLayer = nil
        //previewView = UIView()

        super.init()

        guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return }
        let videoInput: AVCaptureDeviceInput

        do {
            videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
        } catch {
            return
        }

        if (captureSession.canAddInput(videoInput)) {
            captureSession.addInput(videoInput)
        } else {
            failed()
            return
        }

        let metadataOutput = AVCaptureMetadataOutput()

        if (captureSession.canAddOutput(metadataOutput)) {
            captureSession.addOutput(metadataOutput)

            metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            metadataOutput.metadataObjectTypes = [.qr]
        } else {
            failed()
            return
        }

        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.videoGravity = .resizeAspectFill

        //previewView.layer.addSublayer(previewLayer)

    }

import SwiftUI
import Combine


struct ContentView: View {

    @ObservedObject var scanner = Scanner()

    var body: some View {

        //Text("Hello World").layer.addSublayer(scanner.previewLayer)
        //Text("")
        Text("HelloWorld")//.addSublayer(scanner.previewLayer))

            //.previewLayout(scanner.previewLayer)
            .layer.addSublayer(scanner.previewLayer)

            //.previewLayout(scanner.previewLayer)

            //.overlay(scanner.previewView)

        scanner.captureSession.startRunning()

    }
}

尝试添加 previewLayer 时编译错误

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    您不能直接添加图层。这就是为什么人们现在像许多其他东西一样把整个东西都藏在UIView(Controller)Representable 里面。

    【讨论】:

    【解决方案2】:

    我设法将捕获的图像放到 SwiftUI 视图中

    在视图组件中,简单地放一个

    Image(uiImage: cameraManager.capturedImage)
    

    而对于CameraManager,使用帧捕获功能,将采样缓冲区转换为UIImage后,只需将capturedImage设置为uiImage。 (参考https://medium.com/ios-os-x-development/ios-camera-frames-extraction-d2c0f80ed05a

    class CameraManager: NSObject, ObservableObject{
        ...
        @Published public var capturedImage: UIImage = UIImage()
        ...
    }
    

    extension CameraManager: AVCaptureVideoDataOutputSampleBufferDelegate {
    
        func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
    
            // transforming sample buffer to UIImage
            guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
            let ciImage = CIImage(cvPixelBuffer: imageBuffer)
            let context = CIContext()
            guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else { return }
            let uiImage = UIImage(cgImage: cgImage)
            
            // publishing changes to the main thread
            DispatchQueue.main.async {
                self.capturedImage = uiImage
            }
        }
    
    }
    

    我本来打算把每一帧都抓下来做后期图像处理的,虽然现在可以预览了,不知道加了计算机视觉算法,会不会影响抓帧。到现在为止,感觉模型会在另一个线程上运行,所以...

    好吧,欢迎评论

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-21
      • 2022-01-05
      • 1970-01-01
      相关资源
      最近更新 更多