天天看點

iOS7使用原生API進行二維碼和條形碼的掃描

使用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為什麼要設計成這樣,或者是這個參數我的用法那裡不對,還需要了解的朋友給個指導。

繼續閱讀