iOS开发 - 系统自带框架实现扫一扫功能

iOS 扫一扫

利用系统自带框架实现扫一扫功能

一 项目配置

扫一扫功能相机和相册权限,在info.plist中设置询问用户是否允许访问的权限。

info.plist加入NSCameraUsageDescription、NSPhotoLibraryUsageDescription、NSPhotoLibraryAddUsageDescription


	NSCameraUsageDescription
	开启相机权限,活动扫一扫更快捷
	NSPhotoLibraryAddUsageDescription
	添加照片需要您的同意
	NSPhotoLibraryUsageDescription
	开启照片权限,美照当然要人赞!

二 扫一扫权限判断

当每次进入扫一扫页面时,需要判断是否开启了权限


/** 校验是否有相机权限 */
- (void)checkCameraAuthorizationStatus:(void(^)(BOOL granted))permissionGranted
{
    AVAuthorizationStatus videoAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    
    switch (videoAuthStatus) {
            // 已授权
        case AVAuthorizationStatusAuthorized:
        {
            permissionGranted(YES);
        }
            break;
            // 未询问用户是否授权
        case AVAuthorizationStatusNotDetermined:
        {
            // 提示用户授权
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                permissionGranted(granted);
            }];
        }
            break;
            // 用户拒绝授权或权限受限
        case AVAuthorizationStatusRestricted:
        case AVAuthorizationStatusDenied:
        {
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"请在”设置-隐私-相机”选项中,允许访问你的相机" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
            [alert show];
            permissionGranted(NO);
        }
            break;
        default:
            break;
    }
}

三 需要用到AVCaptureDevice、AVCaptureDeviceInput、AVCaptureMetadataOutput、AVCaptureSession、AVCaptureVideoPreviewLayer

  • AVCaptureDevice:捕获设备,通常是前置摄像头,后置摄像头,麦克风(音频输入)
  • AVCaptureDeviceInput:AVCaptureDeviceInput 代表输入设备,使用AVCaptureDevice 来初始化
  • AVCaptureMetadataOutput:输出
  • AVCaptureSession:session 把输入输出结合在一起,并开始启动捕获设备(摄像头)
  • AVCaptureVideoPreviewLayer:图像预览层,实时显示捕获的图像

设置相机


/**
 设置相机
*/
- (void)setupCamera {
    self.avDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    self.avInput = [AVCaptureDeviceInput deviceInputWithDevice:self.avDevice error:nil];
    self.avOutput = [[AVCaptureMetadataOutput alloc]init];
    [self.avOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    self.avSession = [[AVCaptureSession alloc]init];
    [self.avSession setSessionPreset:AVCaptureSessionPresetHigh];
    if ([self.avSession canAddInput:self.avInput]){
        [self.avSession addInput:self.avInput];
    }
    if ([self.avSession canAddOutput:self.avOutput]){
        [self.avSession addOutput:self.avOutput];
    }
    
    // 二维码类型 AVMetadataObjectTypeQRCode
    if ([self.avOutput.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeQRCode]){
        self.avOutput.metadataObjectTypes = [NSArray arrayWithObject:AVMetadataObjectTypeQRCode];
        // AVMetadataObjectTypeAztecCode 条形码
    } else{
        return ;
    }
    
    [self.avSession startRunning];//开始扫描
}

返回预览layer

/**
 显示的预览layer
 
 @return AVCaptureVideoPreviewLayer
 */
- (AVCaptureVideoPreviewLayer *)showPeviewLayer {
    self.avPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.avSession];
    self.avPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    return self.avPreviewLayer;
}


开始扫描与结束扫描

/**
 开始扫描
 */
- (void)startRunning {
    [self.avSession startRunning];
}

/**
 结束扫描
 */
- (void)stopRunning {
    [self.avSession stopRunning];
}


输出扫描结果AVCaptureMetadataOutputObjectsDelegate


#pragma mark - AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:
(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    if ([metadataObjects count] > 0){
        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
        NSString *result = metadataObject.stringValue;//扫描出来的字符串
        NSLog(@"result:%@",result);
        
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"显示扫描结果" message:result delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
        [alert show];
        
        [self.avSession stopRunning];//停止扫描
    }
}

使用

	self.scanConfig = [[INQrScanConfig alloc] init];
        [self.scanConfig setupCamera];
        
        AVCaptureVideoPreviewLayer *previewLayer = [self.scanConfig showPeviewLayer];
        previewLayer.frame = self.layer.bounds;
        [self.layer insertSublayer:previewLayer atIndex:0];
        [self.scanConfig startRunning];

使用

//你要设置的矩形快的frame  为  x1, y1, w1, h1.
    //那么你的 rectOfInterest 应该设置为   (y1/h, x1/w, h1/h, w1/w)
    
    CGFloat size = 260.0;
    CGRect rect = CGRectMake((KAiSysScreenWidth - size)/2, (KAiSysScreenHeight - size)/2, size, size);
    // 使用 (y1/h, x1/w, h1/h, w1/w)
    self.avOutput.rectOfInterest = CGRectMake(rect.origin.y/KAiSysScreenHeight, rect.origin.x/KAiSysScreenWidth, size/KAiSysScreenHeight, size/KAiSysScreenWidth);

结果如图:
iOS开发 - 系统自带框架实现扫一扫功能_第1张图片

你可能感兴趣的:(iphone开发,移动开发,Objective-c,ios,数码相机,扫一扫)