首先给出本文小Deme
二维码的识别包括了两种方法,一种是打开摄像头扫描,一种是扫描相册的图片。
没事的时候写了小demo,接下来分析一下两种方法的实现:
第一种:通过识别相册的图片来识别二维码得到结果
- (void)choicePhoto {
//调用相册
UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init];
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.delegate = self;
[self presentViewController:imagePicker animated:YES completion:nil];
}```
//选中图片的回调
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
//取出选中的图片
UIImage *pickImage = info[UIImagePickerControllerOriginalImage];
self.image = [self alterImageSize:pickImage];
[self dismissViewControllerAnimated:YES completion:^{
[self codeRe];
}];
}
//利用苹果原生的来扫描二维码图片,有时图片太大会造成crash 所以在这里修改一下图片大小,这个问题之前也没遇到过,分享一下,也是学习了
-
(UIImage *)alterImageSize:(UIImage *)originalImage {
UIGraphicsBeginImageContext(originalImage.size);
[originalImage drawInRect:CGRectMake(0, 0, originalImage.size.width, originalImage.size.height)];
UIImage *NewImage = [UIImage imageWithCGImage:[UIGraphicsGetImageFromCurrentImageContext() CGImage]];
return NewImage;
}
-
(void)codeRe {
NSString *content = @"" ;
NSData *imageData = UIImagePNGRepresentation(self.image);
CIImage *ciImage = [CIImage imageWithData:imageData];
//创建探测器
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy: CIDetectorAccuracyLow}];
NSArray *feature = [detector featuresInImage:ciImage];
//取出探测到的数据
for (CIQRCodeFeature *result in feature) {
content = result.messageString;
[self compelet:content];
return;
}
}
识别成功以后给出提示音,停止摄像头,返回之前的页面通过代理传递识别结果。
-
(void)compelet:(NSString *)resultMessageString {
[self playBeep];
[_session stopRunning];
[self.navigationController popViewControllerAnimated:YES];
if ([self.delegate respondsToSelector:@selector(searchReult:)]) {
[self.delegate searchReult:resultMessageString];
}
}
//扫描成功时的提示音
-
(void)playBeep{
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"6005"ofType:@"mp3"]], &soundID);
AudioServicesPlaySystemSound(soundID);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
第二种:通过摄像头,也是常用的方法:
-
(void)startSearch {
NSError *error;
//设备
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//捕捉会话
_session = [[AVCaptureSession alloc] init];
//预先设置高质量的输入输出
[_session setSessionPreset:AVCaptureSessionPresetHigh];
//输入
_input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:&error];
// 输出
_output = [[AVCaptureMetadataOutput alloc] init];
//添加输入与输出设备
if ([_session canAddInput:_input]) {
[_session addInput:_input];
}
if ([_session canAddOutput:_output]) {
[_session addOutput:_output];
}
//设置代理并在主线程中刷新UI
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// _output.rectOfInterest = CGRectMake(100, 100, 100, 100);
//设置扫描范围 output.rectOfInterest
//设置扫描二维码等
[_output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
_previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_session];//预览
_previewLayer.frame = self.view.bounds;
[self.view.layer insertSublayer:_previewLayer atIndex:0];//添加预览图层
[_session startRunning];
}
//判断相机是否可用
-
(ErrorType)isCameraAvisible {
BOOL flag;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
flag = YES;
}else {
flag = NO;
}
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied)
{
flag = NO;
}
return flag;
}
取消的时候dismiss回去
-
(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:nil];
}
-
(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
NSString *conten = @"";
AVMetadataMachineReadableCodeObject *metadataObject = metadataObjects.firstObject;
conten = metadataObject.stringValue;
if (conten.length > 1) {
[self compelet:conten];
}
}
其实大部分是看的别人的代码,自己写的部分还有很多要完善的地方,就当学习啦!