Thursday, April 30, 2015

Bar code reading in iOS


With iOS 7.0 Apple introduced ability to detect the bar code and QR codes using the AV foundation framework. The supported types are UPC-A, UPC-E, Code 39, Code 39 Mode 43, Cdoe 93, Code 128, EAN 8, EAN 13, Aztec, PDF 417, QR 

Detecting bar code programmatically is simple. The below are the main steps involved 

1. Create a CaptureDeviceInput With AVCaptureSession as media type video
2. Create a AVVideoCatptureOutput and set the delegate 
3. Create a AVCapturePReview layer so that viewpoint on the screen 

_session = [[AVCaptureSession alloc] init];
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;

_input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:&error];
if (_input) {
    [_session addInput:_input];
} else {
    NSLog(@"Error: %@", error);
}

_output = [[AVCaptureMetadataOutput alloc] init];
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[_session addOutput:_output];

_output.metadataObjectTypes = [_output availableMetadataObjectTypes];

_prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_prevLayer.frame = self.view.bounds;
_prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:_prevLayer];

[_session startRunning];

Now, when the call back happens, transform the preview layer data to the machine readable code transformed value 

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    CGRect highlightViewRect = CGRectZero;
    AVMetadataMachineReadableCodeObject *barCodeObject;
    NSString *detectionString = nil;
    NSArray *barCodeTypes = @[AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode39Mod43Code,
                              AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code,
                              AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode];
    
    for (AVMetadataObject *metadata in metadataObjects) {
        for (NSString *type in barCodeTypes) {
            if ([metadata.type isEqualToString:type])
            {
                barCodeObject = (AVMetadataMachineReadableCodeObject *)[_prevLayer transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadata];
                highlightViewRect = barCodeObject.bounds;
                detectionString = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
                break;
            }
        }
        
        if (detectionString != nil)
        {
            _label.text = detectionString;
            break;
        }
        else
            _label.text = @"(none)";
    }
    
    _highlightView.frame = highlightViewRect;
}


References:



No comments:

Post a Comment