iOS AV Foundation 二维码扫描 03 为扫描到的二维码添加可视化效

上一节,我们已经实现了二维码的扫描,这一节,,我们利用元数据的bounds和corners实现一个可视化的扫描效果。

bounds定义了包含二维码图像的矩形,corners定义了二维码图像的实际坐标:

当摄像头和二维码图片完全对齐时,bounds和corners就是相同的。但是通常来说,几乎不可能让摄像头和二维码完全对齐。

打开ViewController.m,添加以下实例变量,用于存放所有检测到得二维码,以二维码的内容为索引。

NSMutableDictionary *_barcodes;在viewDidLoad方法中初始化这个字典:

_barcodes = [NSMutableDictionary new];定义一个Barcode类,用于存放已识别的二维码的元数据。

@interface Barcode : NSObject@property (nonatomic, strong) AVMetadataMachineReadableCodeObject *metadataObject;@property (nonatomic, strong) UIBezierPath *cornersPath;@property (nonatomic, strong) UIBezierPath *boundingBoxPath;@end@implementation Barcode@end添加processMetadataObject :

– (Barcode *)processMetadataObject:(AVMetadataMachineReadableCodeObject *)code{// 1Barcode *barcode = _barcodes[code.stringValue];// 2if (!barcode){barcode = [Barcode new];_barcodes[code.stringValue] = barcode;}// 3barcode.metadataObject = code;// Create the path joining code's corners// 4CGMutablePathRef cornersPath = CGPathCreateMutable();// 5CGPoint point;CGPointMakeWithDictionaryRepresentation((CFDictionaryRef)code.corners[0], &point);// 6CGPathMoveToPoint(cornersPath, nil, point.x, point.y);// 7for (int i = 1; i < code.corners.count; i++) {CGPointMakeWithDictionaryRepresentation((CFDictionaryRef)code.corners[i], &point);CGPathAddLineToPoint(cornersPath, nil, point.x, point.y);}// 8CGPathCloseSubpath(cornersPath);// 9barcode.cornersPath =[UIBezierPath bezierPathWithCGPath:cornersPath];CGPathRelease(cornersPath);// Create the path for the code's bounding box// 10barcode.boundingBoxPath = [UIBezierPath bezierPathWithRect:code.bounds];// 11return barcode;}

修改captureOutput:didOutputMetadataObjects:fromConnection方法:

– (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{// 1NSMutableSet *foundBarcodes = [NSMutableSet new];[metadataObjects enumerateObjectsUsingBlock: ^(AVMetadataObject *obj, NSUInteger idx, BOOL *stop) {NSLog(@"Metadata: %@", obj);// 2if ([obj isKindOfClass:[AVMetadataMachineReadableCodeObject class]]){// 3AVMetadataMachineReadableCodeObject *code = (AVMetadataMachineReadableCodeObject*)[_previewLayer transformedMetadataObjectForMetadataObject:obj];// 4Barcode *barcode = [self processMetadataObject:code];[foundBarcodes addObject:barcode];}}];dispatch_sync(dispatch_get_main_queue(), ^{// Remove all old layers// 5NSArray *allSublayers = [_previewView.layer.sublayers copy];[allSublayers enumerateObjectsUsingBlock: ^(CALayer *layer, NSUInteger idx, BOOL *stop) { if (layer != _previewLayer) {[layer removeFromSuperlayer];}}];// Add new layers// 6[foundBarcodes enumerateObjectsUsingBlock: ^(Barcode *barcode, BOOL *stop) {CAShapeLayer *boundingBoxLayer = [CAShapeLayer new]; boundingBoxLayer.path = barcode.boundingBoxPath.CGPath; boundingBoxLayer.lineWidth = 2.0f; boundingBoxLayer.strokeColor =[UIColor greenColor].CGColor; boundingBoxLayer.fillColor =[UIColor colorWithRed:0.0f green:1.0f blue:0.0falpha:0.5f].CGColor; [_previewView.layer addSublayer:boundingBoxLayer];CAShapeLayer *cornersPathLayer = [CAShapeLayer new]; cornersPathLayer.path = barcode.cornersPath.CGPath; cornersPathLayer.lineWidth = 2.0f; cornersPathLayer.strokeColor =[UIColor blueColor].CGColor; cornersPathLayer.fillColor =[UIColor colorWithRed:0.0f green:0.0f blue:1.0falpha:0.5f].CGColor; [_previewView.layer addSublayer:cornersPathLayer];}];});}

编译运行,效果如下:

下一节,我们将为程序添加语音合成功能,自动朗读二维码的内容。

转载请注明出处:

我想去旅行,一个人背包,一个人旅行,

iOS AV Foundation 二维码扫描 03 为扫描到的二维码添加可视化效

相关文章:

你感兴趣的文章:

标签云: