diff --git a/intelliScan-analytic-engine/ContentView.swift b/intelliScan-analytic-engine/ContentView.swift index e654e37..864c6cc 100644 --- a/intelliScan-analytic-engine/ContentView.swift +++ b/intelliScan-analytic-engine/ContentView.swift @@ -4,139 +4,93 @@ // // Created by Simon Rieger on 15.12.23. // - import SwiftUI import AVFoundation import Vision -struct LiveTextRecognitionView: View { - @State private var recognizedText = "" - +struct ContentView: View { + @State private var recognizedText: String = "" + var body: some View { VStack { CameraView(recognizedText: $recognizedText) .edgesIgnoringSafeArea(.all) - .onDisappear { - CameraView.stopSession() - } - - Text("Live erkannter Text:") + + Text("Recognized Text: \(recognizedText)") .padding() - Text(recognizedText) - .padding() - .background(Color.white.opacity(0.7)) } } } -struct LiveTextRecognitionView_Previews: PreviewProvider { - static var previews: some View { - LiveTextRecognitionView() - } -} - -struct CameraView: UIViewRepresentable { +struct CameraView: UIViewControllerRepresentable { @Binding var recognizedText: String - + class Coordinator: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate { - var recognizedText: Binding - var request: VNRecognizeTextRequest? - - init(recognizedText: Binding) { - self.recognizedText = recognizedText - super.init() - - setupVision() + var parent: CameraView + + init(parent: CameraView) { + self.parent = parent } - - func setupVision() { - request = VNRecognizeTextRequest(completionHandler: { (request, error) in - guard let observations = request.results as? [VNRecognizedTextObservation] else { return } - - var recognizedText = "" - for observation in observations { - guard let topCandidate = observation.topCandidates(1).first else { continue } - recognizedText += topCandidate.string + "\n" - } - - self.recognizedText.wrappedValue = recognizedText - }) - - request?.recognitionLevel = .accurate - } - + func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return } - + + let request = VNRecognizeTextRequest { (request, error) in + if let error = error { + print("Error recognizing text: \(error)") + return + } + + if let results = request.results as? [VNRecognizedTextObservation] { + let text = results.compactMap { observation in + observation.topCandidates(1).first?.string + }.joined(separator: "\n") + + DispatchQueue.main.async { + self.parent.recognizedText = text + } + } + } + let handler = VNImageRequestHandler(cvPixelBuffer: imageBuffer, options: [:]) - do { - try handler.perform([request!]) + try handler.perform([request]) } catch { print("Error performing OCR: \(error)") } } } - - static var session: AVCaptureSession? - - static func startSession() { - session?.startRunning() - } - - static func stopSession() { - session?.stopRunning() - } - + func makeCoordinator() -> Coordinator { - return Coordinator(recognizedText: $recognizedText) + return Coordinator(parent: self) } - - func makeUIView(context: Context) -> UIView { - let view = UIView() - - let session = AVCaptureSession() - - guard let device = AVCaptureDevice.default(for: .video) else { return view } - let input = try? AVCaptureDeviceInput(device: device) - - if session.canAddInput(input!) { - session.addInput(input!) + + func makeUIViewController(context: Context) -> UIViewController { + let viewController = UIViewController() + let captureSession = AVCaptureSession() + + guard let camera = AVCaptureDevice.default(for: .video) else { return viewController } + do { + let input = try AVCaptureDeviceInput(device: camera) + captureSession.addInput(input) + } catch { + print("Error setting up camera input: \(error)") + return viewController } - + let output = AVCaptureVideoDataOutput() output.setSampleBufferDelegate(context.coordinator, queue: DispatchQueue(label: "cameraQueue")) - - if session.canAddOutput(output) { - session.addOutput(output) - } - - // Todo: get PreviewLayer working - let previewLayer = AVCaptureVideoPreviewLayer(session: session) + captureSession.addOutput(output) + + let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) + previewLayer.frame = viewController.view.layer.bounds previewLayer.videoGravity = .resizeAspectFill - previewLayer.frame = view.layer.bounds - view.layer.addSublayer(previewLayer) - - CameraView.session = session - - return view - } - - func updateUIView(_ uiView: UIView, context: Context) { - uiView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) - - if context.coordinator.request == nil { - context.coordinator.setupVision() - } - - if AVCaptureDevice.authorizationStatus(for: .video) == .authorized { - CameraView.startSession() - } else { - AVCaptureDevice.requestAccess(for: .video) { granted in - if granted { - CameraView.startSession() - } - } - } + viewController.view.layer.addSublayer(previewLayer) + + captureSession.startRunning() + + return viewController } + + func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} } diff --git a/intelliScan-analytic-engine/intelliScan_analytic_engineApp.swift b/intelliScan-analytic-engine/intelliScan_analytic_engineApp.swift index ba37df1..a53ae75 100644 --- a/intelliScan-analytic-engine/intelliScan_analytic_engineApp.swift +++ b/intelliScan-analytic-engine/intelliScan_analytic_engineApp.swift @@ -11,7 +11,7 @@ import SwiftUI struct intelliScan_analytic_engineApp: App { var body: some Scene { WindowGroup { - LiveTextRecognitionView() + ContentView() } } }