How to read QR code from static image

Viewed 22408

I know that you can use AVFoundation to scan a QR code using the device's camera. Now here comes the problem, how can I do this from an static UIImage object?

7 Answers

None of the answers here were extremely straightforward in regards to returning test messages. Made a tiny extension that works well for me:

https://gist.github.com/freak4pc/3f7ae2801dd8b7a068daa957463ac645

extension UIImage {
    func parseQR() -> [String] {
        guard let image = CIImage(image: self) else {
            return []
        }

        let detector = CIDetector(ofType: CIDetectorTypeQRCode,
                                  context: nil,
                                  options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])

        let features = detector?.features(in: image) ?? []

        return features.compactMap { feature in
            return (feature as? CIQRCodeFeature)?.messageString
        }
    }
}

If you need just a string you can use such code:

class QRToString {

    func string(from image: UIImage) -> String {

        var qrAsString = ""
        guard let detector = CIDetector(ofType: CIDetectorTypeQRCode,
                                        context: nil,
                                        options: [CIDetectorAccuracy: CIDetectorAccuracyHigh]),
            let ciImage = CIImage(image: image),
            let features = detector.features(in: ciImage) as? [CIQRCodeFeature] else {
                return qrAsString
        }

        for feature in features {
            guard let indeedMessageString = feature.messageString else {
                continue
            }
            qrAsString += indeedMessageString
        }

        return qrAsString
    }
}

Objective-C

- (NSString *)readQR {
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{
        CIDetectorAccuracy:CIDetectorAccuracyHigh
    }];
    /// in here you can replace `self` to your image value
    CIImage *ciImage = [[CIImage alloc]initWithImage:self];
    NSArray *features = [detector featuresInImage:ciImage];
    if([features count] == 0) {
        return nil;
    }
    __block NSString *qrString = @"";
    [features enumerateObjectsUsingBlock:^(CIQRCodeFeature  * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        qrString = obj.messageString;
    }];
    return qrString;
}
Related