How do I use the metadataOutputRectOfInterestForRect method and rectOfInterest property to scan a specific area? (QR Code)

前端 未结 8 1940
时光说笑
时光说笑 2020-12-04 18:00

I am building a QR code scanner with Swift and everything works in that regard. The issue I have is that I am trying to make only a small area of the entire visible A

相关标签:
8条回答
  • 2020-12-04 18:52

    Swift 4:

    captureSession?.startRunning()
    let scanRect = CGRect(x: 0, y: 0, width: 100, height: 100)
    let rectOfInterest = layer.metadataOutputRectConverted(fromLayerRect: scanRect)
    metaDataOutput.rectOfInterest = rectOfInterest
    
    0 讨论(0)
  • 2020-12-04 19:01

    I wasn't really able to clarify the issue with metadataOutputRectOfInterestForRect, however, you can directly set the property as well. You need to the have the resolution in width and height of your video, which you can specify in advance. I quickly used the 640*480 setting. As stated in the documentation, these values have to be

    "extending from (0,0) in the top left to (1,1) in the bottom right, relative to the device’s natural orientation".

    See https://developer.apple.com/documentation/avfoundation/avcaptureoutput/1616304-metadataoutputrectofinterestforr

    Below is the code I tried

    var x = scanRect.origin.x/480
    var y = scanRect.origin.y/640
    var width = scanRect.width/480
    var height = scanRect.height/640
    var scanRectTransformed = CGRectMake(x, y, width, height)
    captureMetadataOutput.rectOfInterest = scanRectTransformed
    

    I just tested it on an iOS device and it seems to work.

    Edit

    At least I've solved the metadataOutputRectOfInterestForRect problem. I believe you have to do this after the camera has been properly set up and is running, as the camera's resolution is not yet available.

    First, add a notification observer method within viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("avCaptureInputPortFormatDescriptionDidChangeNotification:"), name:AVCaptureInputPortFormatDescriptionDidChangeNotification, object: nil)
    

    Then add the following method

    func avCaptureInputPortFormatDescriptionDidChangeNotification(notification: NSNotification) {
    
        captureMetadataOutput.rectOfInterest = videoPreviewLayer.metadataOutputRectOfInterestForRect(scanRect)
    
    }
    

    Here you can then reset the rectOfInterest property. Then, in your code, you can display the AVMetadataObject within the didOutputMetadataObjects function

    var rect = videoPreviewLayer.rectForMetadataOutputRectOfInterest(YourAVMetadataObject.bounds)
    
    dispatch_async(dispatch_get_main_queue(),{
         self.qrCodeFrameView.frame = rect
    })
    

    I've tried, and the rectangle was always within the specified area.

    0 讨论(0)
提交回复
热议问题