iOS7之前在iOS中加入扫二维码都是用第三方框架,最流行的框架是ZXing,这个框架用起来很麻烦,因为底层是用c语言写的,用到ios工程里来适配过程很麻烦。庆幸的是ios7之后苹果官方提供了官方的API,这个用起来很方便,只需要引入
#import <AVFoundation/AVFoundation.h>
这个头文件就可以,是不是很简单?
我们现在来讲一下实现部分:
// 1 实例化摄像头设备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// An AVCaptureDevice object abstracts a physical capture device that provides input data (such as audio or video) to an AVCaptureSession object.
// 2 设置输入,把摄像头作为输入设备
// 因为模拟器是没有摄像头的,因此在此最好做个判断
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (error) {
NSLog(@"没有摄像头%@", error.localizedDescription);
return;
}
// 3 设置输出(Metadata元数据)
AVCaptureMetadataOutput *outPut = [[AVCaptureMetadataOutput alloc] init];
CGRect scanCrop =
CGRectMake((readerFrame.size.width - viewFinderSize.width)/2,
(readerFrame.size.height - viewFinderSize.height)/2,
viewFinderSize.width,
viewFinderSize.height);
//设置扫描范围
outPut.rectOfInterest =
CGRectMake(scanCrop.origin.y/readerFrame.size.height,
scanCrop.origin.x/readerFrame.size.width,
scanCrop.size.height/readerFrame.size.height,
scanCrop.size.width/readerFrame.size.width
);
// 3.1 设置输出的代理
// 使用主线程队列,相应比较同步,使用其他队列,相应不同步,容易让用户产生不好的体验。
[outPut setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// 4 拍摄会话
AVCaptureSession *session = [[AVCaptureSession alloc]init];
session.sessionPreset = AVCaptureSessionPreset640x480;
// 添加session的输入和输出
[session addInput:input];
[session addOutput:outPut];
// 4.1 设置输出的格式
[outPut setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
// 5 设置预览图层(用来让用户能够看到扫描情况)
AVCaptureVideoPreviewLayer *preview = [AVCaptureVideoPreviewLayer layerWithSession:session];
// AVCaptureVideoPreviewLayer -- to show the user what a camera is recording
// 5.1 设置preview图层的属性
[preview setVideoGravity:AVLayerVideoGravityResizeAspectFill];
// 5.2设置preview图层的大小
[preview setFrame:self.view.bounds];
//5.3将图层添加到视图的图层
[self.view.layer insertSublayer:preview atIndex:0];
self.previewLayer = preview;
self.session = session;
对于扫描到的二维码信息处理是下面这个方法
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
以上代码是最简单的扫二维码功能实现代码,但我们在实际开发过程中肯定要复杂一些比如需要添加打开闪光灯功能和在相册选择二维码图片进行扫描。其实这个功能很容易实现,直接看代码吧
//实现闪光灯功能代码:
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
if (device.hasTorch) { // 判断设备是否有散光灯
BOOL b = [device lockForConfiguration:&error];
if (!b) {
if (error) {
NSLog(@"lock torch configuration error:%@", error.localizedDescription);
}
return;
}
device.torchMode =
(device.torchMode == AVCaptureTorchModeOff ? AVCaptureTorchModeOn : AVCaptureTorchModeOff);
[device unlockForConfiguration];
}
//实现打开相册功能代码(这个需要注意一个地方就是要实现它的代理方法
UINavigationControllerDelegate, UIImagePickerControllerDelegate
UIImagePickerController *picker = [[UIImagePickerController alloc]init];
picker.delegate = self;
[self presentViewController:picker animated:YES completion:nil];