当前位置: 首页 > 知识库问答 >
问题:

如何在SwiftUI中显示AVCaptureVideoPreviewLayer

田瀚
2023-03-14

在以前版本的swift中,您可以在ViewController中创建AVCaptureVideoPreviewLayer,并使用view将其添加到默认视图中。层添加子层(预览层)。

在SwiftUI ContentView中如何实现这一点?SwiftUI中的所有视图类型似乎都没有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时出现编译错误

共有2个答案

齐运诚
2023-03-14

我设法将捕获的图像放到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
        }
    }

}

我打算捕捉每一帧用于以后的图像处理,虽然现在可以预览,但我不确定通过添加计算机视觉算法,会不会影响帧捕捉。到目前为止,感觉运行模型将在另一个线程上,所以...

好吧,欢迎评论

祁嘉言
2023-03-14

不能直接添加图层。这就是为什么人们现在像其他很多东西一样,把整个东西都塞进了UIView(Controller)Representable

 类似资料:
  • 问题内容: 键盘出现时如何显示完整的列表?键盘隐藏了列表的下部。 我的列表行中有一个textField。当键盘出现时,无法向下滚动以查看完整列表。键盘在列表的前面,而不在列表的“下面”。这是我的编码: 有人可以帮我怎么做吗? 非常感谢你。 问题答案: 这里有一个处理键盘操作的,您可以订阅这样的键盘事件: 然后像这样使用它:

  • 问题内容: 我正在尝试使用Apple的 SwiftUI 制作一个应用程序,我需要有两个按钮在同一行中显示两个不同的视图。 我使用 Xcode beta 7 和 MacOS Catalina beta 7 。我尝试添加一个表示视图的视图,但是无法单击它,而当我尝试在外部进行简单单击并单击该视图时,该视图没有出现。我也尝试过添加一个内部,但是它也不起作用。单击时也无法添加,视图仍然不会出现 我希望该视

  • 我需要创建一个基于现有文本的条形码。我找到了许多解决方案,但没有一个工作,而不是条形码,我看到的只是一个白色矩形。这里是不工作的代码,但也许它会帮助您找到解决方案

  • 问题内容: 我想将两个唯一的警报附加到同一视图。当我使用下面的代码时,只有底部的警报起作用。 我正在macOS Catalina上使用Xcode 11的正式版本。 我希望在设置为true 时显示第一个警报,而在我设置为true时希望显示第二个警报。只有第二个警报显示其状态为true时,但第一个警报不执行任何操作。 问题答案: 第二个调用覆盖了第一个。您真正想要的是指示是否显示警报,以及应该从闭包后

  • 问题内容: 我是SwiftUI的新手。我有三个视图,我希望它们在PageView中。我想像滑动浏览器一样滑动每个“视图”,并希望这些小点表示我所在的视图。 问题答案: 页面控制 您的页面浏览量 您的页面视图控制器 假设您有一个类似的观点 您可以像这样在主swiftUI视图中使用此组件。

  • 问题内容: 我需要使用SwiftUI在我的应用程序中打开ImagePicker,我该怎么做? 我考虑过使用UIImagePickerController,但是我不知道如何在SwiftUI中做到这一点。 问题答案: Xcode 11.4的清理版本可以通过SPM作为Swift软件包获得: https://github.com/ralfebert/ImagePickerView 资源: