iOS系统自带二维码扫描功能实现

 1 #import "ViewController.h"
 2 #import <AVFoundation/AVFoundation.h>
 3 
 4 @interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>
 5 
 6 @property (nonatomic,strong)AVCaptureSession * session;
 7 @property (nonatomic,strong)AVCaptureVideoPreviewLayer * preview;
 8 @end
 9 
10 @implementation ViewController
11 
12 - (void)viewDidLoad {
13     [super viewDidLoad];
14     self.title = @"扫一扫";
15     [self initQrCodeScanning];
16     // Do any additional setup after loading the view, typically from a nib.
17 }
18 - (void)initQrCodeScanning{
19     /**
20      扫描二维码 大概的流程应该是:1.打开设备的摄像头-->2.进行二维码图像捕获-->3.获取捕获的图像进行解析-->4.取得解析结果进行后续的处理。这些流程需要用到AVFoundation这个库
21      */
22     
23     /**
24      上面完成了捕获的设置,但是并未正在开始'扫描',要完成一次扫描的过程,需要用到AVCaptureSession这个类,这个session类把一次扫描看做一次会话,会话开始后才是正在的'扫描'开始,具体代码如下。
25      */
26     self.session = [[AVCaptureSession alloc] init];
27 //    [self.session setSessionPreset:AVCaptureSessionPresetHigh];//扫描的质量
28     //获取摄像头设备
29     AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
30     NSError *error = nil;
31     //创建输入流
32     AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
33     //拍完照片以后,需要一个AVCaptureMetadataOutput对象将获取的'图像'输出,以便进行对其解析
34     AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc] init];
35     
36     if ([self.session canAddInput:input]) {
37         [self.session addInput:input];
38     }else{
39         //出错处理
40         NSLog(@"%@", error);
41         return;
42     }
43     if ([self.session canAddOutput:output]) {
44         [self.session addOutput:output];
45     }
46     //设置输出类型 有二维码 条形码等
47     output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode  //二维码
48                                    ];
49     //获取输出需要设置代理,在代理方法中获取
50     [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
51     
52     /**
53      接下来我们要做的不是立即开始会话(开始扫描),如果你现在调用会话的startRunning方法的话,你会发现屏幕是一片黑,这时由于我们还没有设置相机的取景器的大小。设置取景器需要用到AVCaptureVideoPreviewLayer这个类。具体代码如下:
54      */
55     self.preview = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
56     self.preview.videoGravity = AVLayerVideoGravityResize;
57     [self.preview setFrame:self.view.bounds];//设置取景器的frame
58     [self.view.layer insertSublayer:self.preview atIndex:0];
59     
60 //    CGSize size = self.view.bounds.size;
61 //    CGSize transparentAreaSize = CGSizeMake(200,200);
62 //    CGRect cropRect = CGRectMake((size.width - transparentAreaSize.width)/2, (size.height - transparentAreaSize.height)/2, transparentAreaSize.width, transparentAreaSize.height);
63 //    output.rectOfInterest = CGRectMake(cropRect.origin.y/size.width,
64 //                                       cropRect.origin.x/size.height,
65 //                                       cropRect.size.height/size.height,
66 //                                       cropRect.size.width/size.width);
67     
68     output.rectOfInterest = CGRectMake((124)/[[UIScreen mainScreen] bounds].size.height,(([[UIScreen mainScreen] bounds].size.width-220)/2)/[[UIScreen mainScreen] bounds].size.width,220/[[UIScreen mainScreen] bounds].size.height,220/[[UIScreen mainScreen] bounds].size.width);
69     //开始扫码
70     [self.session startRunning];
71 }
72 
73 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
74     [self.session stopRunning];//停止会话
75     [self.preview removeFromSuperlayer];//移除取景器
76     if (metadataObjects.count > 0) {
77         AVMetadataMachineReadableCodeObject * obj = metadataObjects[0];
78         NSString * result = obj.stringValue;//这就是扫描的结果
79         NSLog(@"outPut result == %@",result);
80     }
81 }
原文地址:https://www.cnblogs.com/wanli-leon/p/12148874.html