声明:
//输入设备
@property (strong,nonatomic)AVCaptureDevice * device;
//设备输入类。这个类用来表示输入数据的硬件设备,配置抽象设备的port
@property (strong,nonatomic)AVCaptureDeviceInput * input;
//输出类。这个支持二维码、条形码等图像数据的识别
@property (strong,nonatomic)AVCaptureMetadataOutput * output;
//会话对象。此类作为硬件设备输入输出信息的桥梁,承担实时获取设备数据的责任
@property (strong,nonatomic)AVCaptureSession * session;
//图层类。用来快速呈现摄像头获取的原始数据
@property (strong,nonatomic)AVCaptureVideoPreviewLayer * preview;
实现:
- (void)setupCamera
{
// 创建AVCaptureDeviceInput输入设备为手机摄像头
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// 创建输入对象
_input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
// 创建输出对象
_output = [[AVCaptureMetadataOutput alloc]init];
//创建AVCaptureMetadataOutput设置好扫描成功回调代理以及回调线程
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//扫一扫区域限制
_output.rectOfInterest =[self rectOfInterestByScanViewRect:imageView.frame];//CGRectMake(0.1, 0, 0.9, 1);//
// 会话对象AVCaptureSession的创建
_session = [[AVCaptureSession alloc]init];
//高质量采集
[_session setSessionPreset:AVCaptureSessionPresetHigh];
//注意必须在输出数据对象加入到当前会话后才能设置识别的数据格式。
if ([_session canAddInput:self.input])
{
[_session addInput:self.input];
}
if ([_session canAddOutput:self.output])
{
[_session addOutput:self.output];
}
// 这里设置为扫描二维码以及条形码 条码类型 AVMetadataObjectTypeQRCode
_output.metadataObjectTypes =@[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode];
// 创建AVCaptureVideoPreviewLayer对象来实时获取摄像头图像,我们需要调用[self.view addSubview: self.scanView]把摄像头获取的图像实时展示在屏幕上
_preview =[AVCaptureVideoPreviewLayer layerWithSession:self.session];
_preview.videoGravity = AVLayerVideoGravityResize;
_preview.frame =self.view.bounds;
[self.view.layer insertSublayer:self.preview atIndex:0];
[self.view bringSubviewToFront:imageView];
// Start 开启扫描识别
[_session startRunning];
}
#pragma mark AVCaptureMetadataOutputObjectsDelegate扫描成功回调代理
//实现captureOutput: didOutputMetadataObjects: fromConnection:来获取扫描得到的数据。回调参数metadataObjects中存放了扫描结果,我们需要先判断这个数组的数据个数不为0再执行下面的代码
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
NSString *stringValue;
if ([metadataObjects count] >0)
{
AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
/**
* 获取扫描结果
*/
stringValue = metadataObject.stringValue;
}
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:[NSString stringWithFormat:@"扫描结果:%@", stringValue] preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Sure" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
//开启扫描识别
[_session startRunning];
}]];
[self presentViewController:alert animated:true completion:nil];
//关闭扫描识别
[_session stopRunning];
}