二维码扫描识别

作者: 努力才幸运 | 来源:发表于2017-05-26 17:36 被阅读263次

    首先给出本文小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];
      }
      }

    其实大部分是看的别人的代码,自己写的部分还有很多要完善的地方,就当学习啦!

    相关文章

      网友评论

        本文标题:二维码扫描识别

        本文链接:https://www.haomeiwen.com/subject/rjoaxxtx.html