본문 바로가기
개발/Swift

SwiftUI 바코드 인식

by Wrmoon 2023. 7. 29.
반응형

이 블로그 글에서는 SwiftUI와 Vision Framework를 사용하여 바코드를 인식하는 방법을 알려드리겠습니다.

Vision Framework는 iOS와 macOS에서 이미지 및 비디오 분석을 위한 강력한 도구로, 바코드 인식과 같은 기능을 구현하는 데에도 탁월한 성능을 보여줍니다.

 

 

import SwiftUI
import Vision

struct BarcodeScannerView: View {
    @State private var scannedBarcode: String?

    var body: some View {
        VStack {
            if let barcode = scannedBarcode {
                Text("Scanned Barcode: \(barcode)")
            } else {
                Text("Place the barcode in front of the camera.")
            }
        }
        .onAppear {
            startScanning()
        }
    }

    func startScanning() {
        let barcodeRequest = VNDetectBarcodesRequest(completionHandler: handleBarcodeDetection)
        let cameraCapture = AVCaptureVideoDataOutput()

        do {
            let captureSession = AVCaptureSession()
            guard let captureDevice = AVCaptureDevice.default(for: .video) else { return }
            let input = try AVCaptureDeviceInput(device: captureDevice)

            if captureSession.canAddInput(input) && captureSession.canAddOutput(cameraCapture) {
                captureSession.addInput(input)
                captureSession.addOutput(cameraCapture)

                let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
                previewLayer.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)

                // SwiftUI View에 AVLayerVideoPreview 추가
                UIApplication.shared.windows.first?.rootViewController?.view.layer.addSublayer(previewLayer)

                cameraCapture.setSampleBufferDelegate(AVCameraDelegate(barcodeRequest: barcodeRequest), queue: DispatchQueue(label: "BarcodeCaptureQueue"))

                captureSession.startRunning()
            }
        } catch {
            print("Error initializing barcode scanner: \(error.localizedDescription)")
        }
    }

    func handleBarcodeDetection(request: VNRequest, error: Error?) {
        if let observations = request.results as? [VNBarcodeObservation] {
            for observation in observations {
                if let payload = observation.payloadStringValue {
                    scannedBarcode = payload
                    return
                }
            }
        }
        scannedBarcode = nil
    }
}

class AVCameraDelegate: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate {
    let barcodeRequest: VNDetectBarcodesRequest

    init(barcodeRequest: VNDetectBarcodesRequest) {
        self.barcodeRequest = barcodeRequest
    }

    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
            return
        }
        let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:])

        do {
            try imageRequestHandler.perform([barcodeRequest])
        } catch {
            print("Error performing barcode request: \(error.localizedDescription)")
        }
    }
}

 

이제 BarcodeScannerView를 호출하는 메인 뷰를 생성하고,

바코드를 스캔하는 데 성공하면 결과를 표시하도록 설정할 수 있습니다.

 

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                BarcodeScannerView()
                    .frame(maxHeight: 300)
                    .cornerRadius(10)
                    .padding()

                Spacer()
            }
            .navigationTitle("Barcode Scanner")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

이제 프로젝트를 빌드하고 iOS 디바이스에서 실행하면 바코드 스캐너를 사용할 수 있습니다. 디바이스의 카메라를 바코드에 대해 정렬하면, 인식된 바코드 값이 화면에 표시됩니다.

 

이렇게 SwiftUI와 Vision Framework를 사용하여 바코드를 인식하는 방법을 알아보았습니다. 바코드 인식에 대한 추가적인 기능을 구현하려면 Vision Framework의 다른 기능과 옵션을 살펴보시기 바랍니다.

반응형

댓글