You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift如何通过Vision框架AVCaptureVideoDataOutput仅扫描指定CGRect区域

基于Vision框架的限定区域条形码扫描实现代码

我正在参考教程学习使用Vision框架实现条形码扫描功能,需求为仅识别屏幕中央指定正方形区域内的条形码。

以下是我当前的捕获输出配置代码,完整代码如下:

import UIKit
import Vision
import AVFoundation

class ViewController: UIViewController {
  // MARK: - 私有变量
  var captureSession = AVCaptureSession()

  // TODO: 定义VNDetectBarcodesRequest变量
  lazy var detectBarcodeRequest = VNDetectBarcodesRequest { request, error in
    guard error == nil else {
      print("条形码识别错误:\(error?.localizedDescription ?? "")")
      return
    }
    self.processClassification(request)
  }

  // MARK: - 生命周期重写方法
  override func viewDidLoad() {
    super.viewDidLoad()
    checkPermissions()
    setupCameraLiveView()
  }
  override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    // TODO: 停止捕获会话
    captureSession.stopRunning()
  }
}

处理输出

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

权限校验、输入输出添加逻辑

extension ViewController {
  // MARK: - 相机相关方法
    private func checkPermissions() {
    // TODO: 校验相机权限
      switch AVCaptureDevice.authorizationStatus(for: .video) {
      case .notDetermined:
        AVCaptureDevice.requestAccess(for: .video) { granted in
           if !granted {
            print("请前往设置页为当前应用授予相机使用权限")
         }
       }
    case .denied, .restricted:
      print("请前往设置页为当前应用授予相机使用权限")
    default:
      return
    }
  }

  private func setupCameraLiveView() {
    // TODO: 配置捕获会话
    captureSession.sessionPreset = .hd1280x720

    // TODO: 添加视频输入
    let videoDevice = AVCaptureDevice
      .default(.builtInWideAngleCamera, for: .video, position: .back)

    guard
      let device = videoDevice,
      let videoDeviceInput = try? AVCaptureDeviceInput(device: device),
      captureSession.canAddInput(videoDeviceInput) else {
        print("当前设备相机存在异常,无法使用")
        return
      }

    captureSession.addInput(videoDeviceInput)

    // TODO: 添加视频输出
    let captureOutput = AVCaptureVideoDataOutput()
    // TODO: 设置视频采样率
    captureOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]
    captureOutput.setSampleBufferDelegate(self, queue: DispatchQueue.global(qos: DispatchQoS.QoSClass.default))
    captureSession.addOutput(captureOutput)

    configurePreviewLayer()

    // TODO: 启动捕获会话
    captureSession.startRunning()
  }

  // MARK: - Vision识别逻辑
  func processClassification(_ request: VNRequest) {
    // TODO: 识别结果主处理逻辑
    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: 校验二维码编码类型与置信度
            let potentialQRCode = barcode as? VNBarcodeObservation,
            potentialQRCode.symbology == .QR
            else { return }

          print("识别到的二维码内容:\(potentialQRCode.payloadStringValue ?? "")")
        }
      }
    }
  }
}

预览层配置逻辑

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)
          }
        }

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 04:39:05