AVFoundation识别二维码并加边框

目标:识别二维码,并且在视频流中,在已识别的二维码周边加上边框。

#import "ViewController.h"
#import 

@interface ViewController ()

@property (nonatomic, strong) AVCaptureSession *session;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *preview;

@property (nonatomic, strong) CALayer *drawLayer;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    // session
    _session = [[AVCaptureSession alloc] init];
    
    // input
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    AVCaptureDeviceInput *input = [[AVCaptureDeviceInput alloc] initWithDevice:device error:nil];
    
    // output
    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    
    // addInput, addOutput
    if ([_session canAddInput:input]) {
        [_session addInput:input];
    }
    if ([_session canAddOutput:output]) {
        [_session addOutput:output];
    }
    
    output.metadataObjectTypes = output.availableMetadataObjectTypes;
    
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    _preview = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_session];
    _preview.frame = self.view.bounds;
    
    _drawLayer = [CALayer layer];
    _drawLayer.frame = self.view.bounds;
}


- (IBAction)testButton1:(id)sender {
    
    if (_session.isRunning) {
        [_preview removeFromSuperlayer];
        [_drawLayer removeFromSuperlayer];
        [_session stopRunning];
    } else {
        [self.view.layer insertSublayer:_drawLayer atIndex:0];
        [self.view.layer insertSublayer:_preview atIndex:0];
        [_session startRunning];
        
    }
}

- (void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    
    NSArray *layers = _drawLayer.sublayers.copy;
    for (CALayer *layer in layers) {
        [layer removeFromSuperlayer];
    }
    
    for (AVMetadataObject *obj in metadataObjects) {
        if ([obj isKindOfClass:AVMetadataMachineReadableCodeObject.class]) {
            //将0-1间小数表示的坐标系转换为常用的坐标系
            AVMetadataMachineReadableCodeObject *temp = (AVMetadataMachineReadableCodeObject*)[_preview transformedMetadataObjectForMetadataObject:obj];
            [self addBorderOnOjbect:(AVMetadataMachineReadableCodeObject *)temp];
        }
    }
}

//添加一个中间是透明的,周边是有颜色的layer
- (void)addBorderOnOjbect:(AVMetadataMachineReadableCodeObject *)obj {
    
    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.lineWidth = 4;
    layer.strokeColor = UIColor.greenColor.CGColor;
    layer.fillColor = UIColor.clearColor.CGColor;
    layer.path = [self boderPathWithObject:obj].CGPath;
    
    [_drawLayer addSublayer:layer];
    
}

//获取边框的path
- (UIBezierPath *)boderPathWithObject:(AVMetadataMachineReadableCodeObject *)obj {
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    NSArray *corners = obj.corners;
    CGPoint point = CGPointZero; int index = 0;
    //将corner里0-1小数表示的坐标点转换为常用的坐标点。
    CGPointMakeWithDictionaryRepresentation((CFDictionaryRef)corners[index++], &point);
    [path moveToPoint:point];
    
    while (index < corners.count) {
        CGPointMakeWithDictionaryRepresentation((CFDictionaryRef)corners[index++], &point);
        [path addLineToPoint:point];
    }
    [path closePath];
    return path;
}

@end

你可能感兴趣的:(AVFoundation识别二维码并加边框)