二維碼掃描
ios7之前我們實(shí)現(xiàn)二維碼掃描一般是借助第三方來實(shí)現(xiàn)赏表,但是在ios7之后系統(tǒng)自己提供二維碼掃面的方法,而且用原生的方法性能要比第三方的要好很多
@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>//用于處理采集信息的代理
{
AVCaptureSession * session;//輸入輸出的中間橋梁
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//獲取攝像設(shè)備
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//創(chuàng)建輸入流
AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if (!input) return;
//創(chuàng)建輸出流
AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];
//設(shè)置代理 在主線程里刷新
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//設(shè)置有效掃描區(qū)域
CGRect scanCrop=[self getScanCrop:_scanWindow.bounds readerViewBounds:self.view.frame];
output.rectOfInterest = scanCrop;
//初始化鏈接對象
_session = [[AVCaptureSession alloc]init];
//高質(zhì)量采集率
[_session setSessionPreset:AVCaptureSessionPresetHigh];
[_session addInput:input];
[_session addOutput:output];
//設(shè)置掃碼支持的編碼格式(如下設(shè)置條形碼和二維碼兼容)
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];
}
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if (metadataObjects.count>0) {
//[session stopRunning];
AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0 ];
//輸出掃描字符串
NSLog(@"%@",metadataObject.stringValue);
//移除layer,停止掃描
}
}
一些初始化的代碼加上實(shí)現(xiàn)代理方法便完成了二維碼掃描的工作迎变,這里我們需要注意的是, 在二維碼掃描的時候, 我們一般都會在屏幕中間放一個方框沿侈,用來顯示二維碼掃描的大小區(qū)間,這里我們在個AVCaptureMetadataOutput類中有一個rectOfInterest屬性市栗,它的作用就是設(shè)置掃描范圍缀拭。
這個CGRect參數(shù)和普通的Rect范圍不太一樣,它的四個值的范圍都是0-1填帽,表示比例蛛淋。
rectOfInterest都是按照橫屏來計(jì)算的 所以當(dāng)豎屏的情況下 x軸和y軸要交換一下。
寬度和高度設(shè)置的情況也是類似篡腌。
我們在上面設(shè)置有效掃描區(qū)域的方法如下
#pragma mark-> 獲取掃描區(qū)域的比例關(guān)系
-(CGRect)getScanCrop:(CGRect)rect readerViewBounds:(CGRect)readerViewBounds
{
CGFloat x,y,width,height;
x = (CGRectGetHeight(readerViewBounds)-CGRectGetHeight(rect))/2/CGRectGetHeight(readerViewBounds);
y = (CGRectGetWidth(readerViewBounds)-CGRectGetWidth(rect))/2/CGRectGetWidth(readerViewBounds);
width = CGRectGetHeight(rect)/CGRectGetHeight(readerViewBounds);
height = CGRectGetWidth(rect)/CGRectGetWidth(readerViewBounds);
return CGRectMake(x, y, width, height);
}