使用iOS7原生API進行二維碼條形碼的掃描
IOS7之前,開發者進行掃碼程式設計時,一般會借助第三方庫。常用的是ZBarSDK,IOS7之後,系統的AVMetadataObject類中,為我們提供了解析二維碼的接口。經過測試,使用原生API掃描和處理的效率非常高,遠遠高于第三方庫。
一、使用方法示例
官方提供的接口非常簡單,代碼如下:
@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>//用于處理采集資訊的代理
{
AVCaptureSession * session;//輸入輸出的中間橋梁
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//擷取攝像裝置
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//建立輸入流
AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
//建立輸出流
AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];
//設定代理 在主線程裡重新整理
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//初始化連結對象
session = [[AVCaptureSession alloc]init];
//高品質采集率
[session setSessionPreset:AVCaptureSessionPresetHigh];
[session addInput:input];
[session addOutput:output];
//設定掃碼支援的編碼格式(如下設定條形碼和二維碼相容)
output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayer layerWithSession:session];
layer.videoGravity=AVLayerVideoGravityResizeAspectFill;
layer.frame=self.view.layer.bounds;
[self.view.layer insertSublayer:layer atIndex:0];
//開始捕獲
[session startRunning];
之後我們的UI上已經可以看到攝像頭捕獲的内容,隻要實作代理中的方法,就可以完成二維碼條形碼的掃描:
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if (metadataObjects.count>0) {
//[session stopRunning];
AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0 ];
//輸出掃描字元串
NSLog(@"%@",metadataObject.stringValue);
}
二、一些優化
通過上面的代碼測試,我們可以發現系統的解析處理效率是相當的高,IOS官方提供的API也确實非常強大,然而,我們可以做進一步的優化,将效率更加提高:
首先,AVCaptureMetadataOutput類中有一個這樣的屬性(在IOS7.0之後可用):
@property(nonatomic) CGRect rectOfInterest;
這個屬性大緻意思就是告訴系統它需要注意的區域,大部分APP的掃碼UI中都會有一個框,提醒你将條形碼放入那個區域,這個屬性的作用就在這裡,它可以設定一個範圍,隻處理在這個範圍内捕獲到的圖像的資訊。如此一來,可想而知,我們代碼的效率又會得到很大的提高,在使用這個屬性的時候。需要幾點注意:
1、這個CGRect參數和普通的Rect範圍不太一樣,它的四個值的範圍都是0-1,表示比例。
2、經過測試發現,這個參數裡面的x對應的恰恰是距離左上角的垂直距離,y對應的是距離左上角的水準距離。
3、寬度和高度設定的情況也是類似。
3、舉個例子如果我們想讓掃描的處理區域是螢幕的下半部分,我們這樣設定
output.rectOfInterest=CGRectMake(0.5,0,0.5, 1);
具體apple為什麼要設計成這樣,或者是這個參數我的用法那裡不對,還需要了解的朋友給個指導。