#import "FirstViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface FirstViewController () <AVCaptureMetadataOutputObjectsDelegate> // 要遵守这个协议
@property (strong, nonatomic) UILabel *captureLabel; // 显示获取的二维码信息
@property (strong, nonatomic) AVCaptureSession *session; // 二维码生成的图像
@property (strong, nonatomic) AVCaptureVideoPreviewLayer *previewLayer; // 二维码生成的图层
@end
@implementation FirstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.captureLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 500, 280, 40)];
self.captureLabel.numberOfLines = 0;
self.captureLabel.textAlignment = NSTextAlignmentCenter;
self.captureLabel.font = [UIFont systemFontOfSize:13];
[self.view addSubview:self.captureLabel];
UIButton *readButton = [UIButton buttonWithType:UIButtonTypeCustom];
[readButton setTitle:@"扫描" forState:UIControlStateNormal];
readButton.backgroundColor = [UIColor greenColor];
readButton.titleLabel.textColor = [UIColor blackColor];
readButton.frame = CGRectMake(120, 450, 80, 30);
[readButton addTarget:self action:@selector(readButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:readButton];
}
#pragma mark - read QR code
-(void)readQRcode
{
// 摄像头设备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// 设置输入
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (error) {
NSLog(@"No camera: %@",error.localizedDescription);
return;
}
// 设置输出(Metadata元数据)
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
// 设置输出的代理
// 说明:使用主线程队列,相应比较同步,使用其他队列,用户体验不好。
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// [output setMetadataObjectsDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
// 拍摄会话
AVCaptureSession *session = [[AVCaptureSession alloc] init];
// 添加session的输入和输出
[session addInput:input];
[session addOutput:output];
// 设置输出的格式
// 提示:一定要先设置会话的输出为output之后,在指定输出的元数据类型
[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
// 设置预览图层,用来让用户能够看到扫描情况
AVCaptureVideoPreviewLayer *preview = [AVCaptureVideoPreviewLayer layerWithSession:session];
// 设置preview图层的属性
[preview setVideoGravity:AVLayerVideoGravityResizeAspectFill];
// 设置preview图层的大小
[preview setFrame:self.view.bounds];
// 将图层添加到视图的图层
[self.view.layer insertSublayer:preview above:0];
self.previewLayer = preview;
// 启动会话
[session startRunning];
self.session = session;
}
#pragma mark - output delegate method
// 此方法是在识别到QRCode时被调用,并且完成转换。QRCode的内容越大,转换的时间越长
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
// 会频繁的扫描,调用代理方法
// 如果扫描完成,停止会话
[self.session stopRunning];
// 删除预览图层
[self.previewLayer removeFromSuperlayer];
NSLog(@"%@",metadataObjects);
// 设置界面显示扫描结果
if (metadataObjects.count > 0) {
AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
// 提示:如果需要对url或者名片等信息进行扫描,可以在此进行扩展。
self.captureLabel.text = obj.stringValue;
}
}
//
-(void)readButtonClicked:(id)sender
{
[self readQRcode];
}
#import <AVFoundation/AVFoundation.h>
@interface FirstViewController () <AVCaptureMetadataOutputObjectsDelegate> // 要遵守这个协议
@property (strong, nonatomic) UILabel *captureLabel; // 显示获取的二维码信息
@property (strong, nonatomic) AVCaptureSession *session; // 二维码生成的图像
@property (strong, nonatomic) AVCaptureVideoPreviewLayer *previewLayer; // 二维码生成的图层
@end
@implementation FirstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.captureLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 500, 280, 40)];
self.captureLabel.numberOfLines = 0;
self.captureLabel.textAlignment = NSTextAlignmentCenter;
self.captureLabel.font = [UIFont systemFontOfSize:13];
[self.view addSubview:self.captureLabel];
UIButton *readButton = [UIButton buttonWithType:UIButtonTypeCustom];
[readButton setTitle:@"扫描" forState:UIControlStateNormal];
readButton.backgroundColor = [UIColor greenColor];
readButton.titleLabel.textColor = [UIColor blackColor];
readButton.frame = CGRectMake(120, 450, 80, 30);
[readButton addTarget:self action:@selector(readButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:readButton];
}
#pragma mark - read QR code
-(void)readQRcode
{
// 摄像头设备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// 设置输入
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (error) {
NSLog(@"No camera: %@",error.localizedDescription);
return;
}
// 设置输出(Metadata元数据)
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
// 设置输出的代理
// 说明:使用主线程队列,相应比较同步,使用其他队列,用户体验不好。
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// [output setMetadataObjectsDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
// 拍摄会话
AVCaptureSession *session = [[AVCaptureSession alloc] init];
// 添加session的输入和输出
[session addInput:input];
[session addOutput:output];
// 设置输出的格式
// 提示:一定要先设置会话的输出为output之后,在指定输出的元数据类型
[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
// 设置预览图层,用来让用户能够看到扫描情况
AVCaptureVideoPreviewLayer *preview = [AVCaptureVideoPreviewLayer layerWithSession:session];
// 设置preview图层的属性
[preview setVideoGravity:AVLayerVideoGravityResizeAspectFill];
// 设置preview图层的大小
[preview setFrame:self.view.bounds];
// 将图层添加到视图的图层
[self.view.layer insertSublayer:preview above:0];
self.previewLayer = preview;
// 启动会话
[session startRunning];
self.session = session;
}
#pragma mark - output delegate method
// 此方法是在识别到QRCode时被调用,并且完成转换。QRCode的内容越大,转换的时间越长
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
// 会频繁的扫描,调用代理方法
// 如果扫描完成,停止会话
[self.session stopRunning];
// 删除预览图层
[self.previewLayer removeFromSuperlayer];
NSLog(@"%@",metadataObjects);
// 设置界面显示扫描结果
if (metadataObjects.count > 0) {
AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
// 提示:如果需要对url或者名片等信息进行扫描,可以在此进行扩展。
self.captureLabel.text = obj.stringValue;
}
}
//
-(void)readButtonClicked:(id)sender
{
[self readQRcode];
}