0

I am following a tutorial about how to use the Vision framework to scan a barcode, and I want to scan a barcode only with a specific square in the center of the screen like this.

This is my code setting capture output add output and output.

import UIKit
import Vision
import AVFoundation

class ViewController: UIViewController {
  // MARK: - Private Variables
  var captureSession = AVCaptureSession()

  // TODO: Make VNDetectBarcodesRequest variable
  lazy var detectBarcodeRequest = VNDetectBarcodesRequest { request, error in
    guard error == nil else {
      print("Barcode error \(error?.localizedDescription ?? "")")
      return
    }
    self.processClassification(request)
  }

  // MARK: - Override Functions
  override func viewDidLoad() {
    super.viewDidLoad()
    checkPermissions()
    setupCameraLiveView()
  }
  override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    // TODO: Stop Session
    captureSession.stopRunning()
  }
}

handle output

extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate {
      func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        // TODO: Live Vision
        guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
    
        let imageRequestHandler = VNImageRequestHandler(
          cvPixelBuffer: pixelBuffer,
          orientation: .right)
    
        do {
          try imageRequestHandler.perform([detectBarcodeRequest])
        } catch {
          print(error)
        }
      }
    }

Check permission, add input output

  extension ViewController {
  // MARK: - Camera
    private func checkPermissions() {
    // TODO: Checking permissions
      switch AVCaptureDevice.authorizationStatus(for: .video) {
      case .notDetermined:
        AVCaptureDevice.requestAccess(for: .video) { granted in
           if !granted {
            print("Please open Settings and grant permission for this app to use your camera.")
         }
       }
    case .denied, .restricted:
      print("Please open Settings and grant permission for this app to use your camera.")
    default:
      return
    }
  }

  private func setupCameraLiveView() {
    // TODO: Setup captureSession
    captureSession.sessionPreset = .hd1280x720

    // TODO: Add input
    let videoDevice = AVCaptureDevice
      .default(.builtInWideAngleCamera, for: .video, position: .back)

    guard
      let device = videoDevice,
      let videoDeviceInput = try? AVCaptureDeviceInput(device: device),
      captureSession.canAddInput(videoDeviceInput) else {
        print("There seems to be a problem with the camera on your device.")
        return
      }

    captureSession.addInput(videoDeviceInput)

    // TODO: Add output
    let captureOutput = AVCaptureVideoDataOutput()
    // TODO: Set video sample rate
    captureOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]
    captureOutput.setSampleBufferDelegate(self, queue: DispatchQueue.global(qos: DispatchQoS.QoSClass.default))
    captureSession.addOutput(captureOutput)

    configurePreviewLayer()

    // TODO: Run session
    captureSession.startRunning()
  }

  // MARK: - Vision
  func processClassification(_ request: VNRequest) {
    // TODO: Main logic
    guard let barcodes = request.results else { return }
    DispatchQueue.main.async { [self] in
      if captureSession.isRunning {
        view.layer.sublayers?.removeSubrange(1...)

        for barcode in barcodes {
          guard
            // TODO: Check for QR Code symbology and confidence score
            let potentialQRCode = barcode as? VNBarcodeObservation,
            potentialQRCode.symbology == .QR
            else { return }

          print("your value: \(potentialQRCode.payloadStringValue ?? "")")
        }
      }
    }
  }
}

config preview layer

extension ViewController {
          private func configurePreviewLayer() {
            let cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            cameraPreviewLayer.videoGravity = .resizeAspectFill
            cameraPreviewLayer.connection?.videoOrientation = .portrait
            cameraPreviewLayer.frame = view.frame
            view.layer.insertSublayer(cameraPreviewLayer, at: 0)
          }
        }
James
  • 3
  • 2

0 Answers0