ios - AV Foundation 相机扫描盒子内

标签 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()

    }

最佳答案

尝试为您的AVCaptureMetaDataOutput设置rectOfInterest

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

根据documentation

rectOfInterest A rectangle of interest for limiting the search area for visual metadata.

The value of this property is a CGRect value that determines the object’s rectangle of interest for each frame of video.

The rectangle's origin is top left and is relative to the coordinate space of the device providing the metadata.

Specifying a rectangle of interest may improve detection performance for certain types of metadata. Metadata objects whose bounds do not intersect with the rectOfInterest will not be returned.

The default value of this property is a rectangle of (0.0, 0.0, 1.0, 1.0).

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

关于ios - AV Foundation 相机扫描盒子内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41340123/

相关文章:

ios - 无法在 iOS 中使用 SwiftyJson 将 JSON 数组或 JSON 对象分配给 JSON

swift - 尝试使IOS应用说泰卢固语。没有语音输出。但是,它适用于其他语言

iphone - iPhone 不支持 ExposureMode AVCaptureExposureModeAutoExpose

ios - 应用程序在运行视频一段时间后进入后台模式

android - react-native-keyboard-aware-scroll-view 中平台之间的不同行为

ios - iOS:如何获取Youtube视频流网址?

objective-c - 在分配实例之前尝试访问静态属性时发生崩溃

swift - 将 ARFaceGeometry 保存到 OBJ 文件

ios - 如何在 iOS 中动态改变视频的播放速率?

ios - 如何获取另一个应用程序当前正在播放的音频