AV基金会相机内扫描

时间:2016-12-27 06:30:06

标签: ios swift avfoundation barcode-scanner

enter image description here

我能够成功扫描完全相机分辨率的条形码,但我希望它只扫描特定帧内的条形码(中央放置的盒子)。如果条形码位于该帧之外,则不应扫描。

var session         : AVCaptureSession = AVCaptureSession()
    var previewLayer    : AVCaptureVideoPreviewLayer!
    var highlightView   : UIView = UIView()

func opencamera()
    {
      if session.running
        {

        }
        else
        {
            session = AVCaptureSession()

            // Set the captureDevice.

            let videoCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)

            session.sessionPreset = AVCaptureSessionPresetInputPriority
            // Create input object.
            let videoInput: AVCaptureDeviceInput?

            do {
                videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
            } catch {
                return
            }

            // Add input to the session.
            if (session.canAddInput(videoInput)) {
                session.addInput(videoInput)
            } else {
                scanningNotPossible()
            }
            let metadataOutput = AVCaptureMetadataOutput()

            // Add output to the session.
            if (session.canAddOutput(metadataOutput)) {
                session.addOutput(metadataOutput)

                // Send captured data to the delegate object via a serial queue.
                metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())

                // Set barcode type for which to scan: EAN-13.
                //metadataOutput.metadataObjectTypes = metadataOutput.availableMetadataObjectTypes
                metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeUPCECode,
                                                      AVMetadataObjectTypeCode39Code,
                                                      AVMetadataObjectTypeCode39Mod43Code,
                                                      AVMetadataObjectTypeEAN13Code,
                                                      AVMetadataObjectTypeEAN8Code,
                                                      AVMetadataObjectTypeCode93Code,
                                                      AVMetadataObjectTypeCode128Code,
                                                      AVMetadataObjectTypePDF417Code,

                ]

            } else {
                scanningNotPossible()
            }
            previewLayer = AVCaptureVideoPreviewLayer(session: session);
            previewLayer.frame = self.view.frame

            previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
            previewLayer?.position = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds))
                           image.layer.addSublayer(previewLayer);
                            session.startRunning()
        }
    }
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {

        //var highlightViewRect = CGRectZero

        // var barCodeObject : AVMetadataObject!

        var detectionString : String!

        let barCodeTypes = [AVMetadataObjectTypeUPCECode,
                            AVMetadataObjectTypeCode39Code,
                            AVMetadataObjectTypeCode39Mod43Code,
                            AVMetadataObjectTypeEAN13Code,
                            AVMetadataObjectTypeEAN8Code,
                            AVMetadataObjectTypePDF417Code,
                            ]


        // The scanner is capable of capturing multiple 2-dimensional barcodes in one scan.
        for metadata in metadataObjects {

            for barcodeType in barCodeTypes {


                let decodedData:  AVMetadataMachineReadableCodeObject =  metadata as! AVMetadataMachineReadableCodeObject
                if metadata.type == barcodeType {

                                           detectionString = (metadata as! AVMetadataMachineReadableCodeObject).stringValue
                    if(metadata.type  == AVMetadataObjectTypeEAN13Code){
                        if (detectionString.hasPrefix("0") && detectionString.characters.count > 1){
                            detectionString = String(detectionString.characters.dropFirst())
                        }

                    }
                    AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
                    self.session.stopRunning()

                    break
                }



            }
        }

        print(detectionString)

        self.previewLayer.removeFromSuperlayer()
        self.highlightView.removeFromSuperview()

    }

1 个答案:

答案 0 :(得分:0)

尝试为rectOfInterest设置AVCaptureMetaDataOutput

self.metadataOutput.rectOfInterest = [self.previewLayer metadataOutputRectOfInterestForRect:myRectOfInterest];

根据documentation

  

rectOfInterest用于限制搜索区域的感兴趣的矩形   用于视觉元数据。

     

此属性的值是一个CGRect值,用于确定   对象的每个视频帧感兴趣的矩形。

     

矩形的原点位于左上角,相对于坐标   提供元数据的设备空间。

     

指定感兴趣的矩形可以提高检测性能   对于某些类型的元数据。边界不包含的元数据对象   不会返回与rectOfInterest相交的。

     

此属性的默认值是(0.0,0.0,1.0,   1.0)。

请注意,该值不是您的像素。要了解更多信息,请查看SO回答herehere