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];