Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to detect Barcode and QR code #973

Open
onmyway133 opened this issue Jun 6, 2024 · 1 comment
Open

How to detect Barcode and QR code #973

onmyway133 opened this issue Jun 6, 2024 · 1 comment

Comments

@onmyway133
Copy link
Owner

Before iOS 11, we used to use CIDetector and CIDetectorTypeQRCode to detect QR code

CIDetector

An image processor that identifies notable features, such as faces and barcodes, in a still image or video.

CIDetectorTypeQRCode

A detector that searches for Quick Response codes (a type of 2D barcode) in a still image or video, returning CIQRCodeFeature objects that provide information about detected barcodes.

func readQrOnly(image: CGImage) async -> String? {
    let ciImage = CIImage(cgImage: image)
    
    let detector = CIDetector(
        ofType: CIDetectorTypeQRCode,
        context: nil,
        options: [
            CIDetectorAccuracy: CIDetectorAccuracyHigh
        ]
    )
    
    guard
        let detector = detector
    else { return nil }
    
    let features = detector
        .features(in: ciImage)
        .compactMap { $0 as? CIQRCodeFeature }
    
    guard
        !features.isEmpty
    else { return nil }
    
    return features
        .compactMap(\.messageString)
        .joined(separator: " ")
}

In macOS 10.13, iOS 11, and tvOS 11 or later, the Vision framework replaces these classes for identifying and analyzing image features.

Using VNRequest, and particular VNDetectBarcodesRequest, we can detect barcodes in an image. It supports a bunch of code types, in form of VNBarcodeSymbology

func read(image: CGImage) async -> VNBarcodeObservation? {
    await withCheckedContinuation { con in
        do {
            let request = VNDetectBarcodesRequest(completionHandler: { request, error in
                if let request = request as? VNDetectBarcodesRequest,
                   let result = request.results?.first {
                    con.resume(returning: result)
                } else {
                    con.resume(returning: VNBarcodeObservation?.none)
                }
            })
            request.symbologies = try request.supportedSymbologies()
            request.revision = VNDetectBarcodesRequestRevision1
            
            let handler = VNImageRequestHandler(cgImage: image)
            try handler.perform([request])
        } catch {
            con.resume(returning: VNBarcodeObservation?.none)
        }
    }
}

Note we have to use VNDetectBarcodesRequestRevision1 for now since the default VNDetectBarcodesRequestRevision4 does not seem to work.

With VNBarcodeObservation, we can read payloadStringValue and symbology to get content and which code type it has detected

@LeXuanKhanh
Copy link

It seems like other revisions except VNDetectBarcodesRequestRevision1 do not work on the simulator, the latestVNDetectBarcodesRequestRevision4 still works on real devices (tested on simulator iOS 17.2 and iPhone 11 Pro with iOS 17.5.1)
another issue related to this StackOverflow but this doesn't happen to me:
https://stackoverflow.com/questions/73770477/vndetectbarcodesrequest-not-working-on-ios16

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants