iOS 可以自己识别二维码,完全不用去找第三方文件。
摄像头用AVFoundation来实现:
@property (strong, nonatomic) AVCaptureSession *session;//整个捕捉过程的中心
@property (strong, nonatomic) AVCaptureDeviceInput *inputDevice;//输入设备
@property (strong, nonatomic) AVCaptureMetadataOutput *metadataOutput;//输出设备
@property (strong, nonatomic) AVCaptureVideoPreviewLayer *previewLayer;//预览层
NSError *err = nil;
//init session
_session = [[AVCaptureSession alloc]init];
_session.sessionPreset = AVCaptureSessionPresetHigh;//图像质量,设置的高点,识别的准点
//add input
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
_inputDevice = [AVCaptureDeviceInput deviceInputWithDevice:device error:&err];
if (!err) {
if ([_session canAddInput:_inputDevice]) {
[_session addInput:_inputDevice];
}
}else{
NSLog(@"err: %@", err);
}
//add output,output有多种,包括输出图片、视频文件等。AVCaptureMetadataOutput逐帧向代理发送数据
_metadataOutput = [[AVCaptureMetadataOutput alloc]init];
[_metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
/*
一般扫码的UI中都有一个maskView,所以应特别注意表示识别范围的属性rectOfInterest:
它的四个值的范围都是0-1,表示比例,x对应的恰恰是距离左上角的垂直距离,y对应的是距离左上角的水平距离。
*/
_metadataOutput.rectOfInterest = CGRectMake(...);
if ([_session canAddOutput:_metadataOutput]) {
[_session addOutput:_metadataOutput];
}
_metadataOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];//要捕捉的数据是二维码
//init preview
_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
_previewLayer.frame = _screenRect;
[self.view.layer insertSublayer:_previewLayer atIndex:0];
[_session startRunning];
处理二维码的方法在代理中:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if ([metadataObjects count] > 0) {//捕捉到了二维码
[_session stopRunning];//关闭摄像头
AVMetadataMachineReadableCodeObject *metadataObject = metadataObjects[0];//得到该二维码对象,然后进行处理
NSString *value = metadataObject.stringValue;//用最粗暴的方式,直接拿了value
NSLog(@"%@", value);
...
}
需要注意的有:
-(void)viewDidDisappear:(BOOL)animated{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{//如果在主线程上关闭,会崩溃
[_session stopRunning];
});
}