美文网首页
iOS 原生扫码二维码与自定义相机

iOS 原生扫码二维码与自定义相机

作者: 牛程程 | 来源:发表于2018-07-23 23:03 被阅读0次

    实现扫码二维码与自定义相机的功能,都要用到 AVFoundation 框架。
    完成功能后发现,这俩个功能在实现上大致相同,唯一不同的地方是 设置 AVCaptureSession 的 output。

    扫描二维码

     self.metadataOutput = [AVCaptureMetadataOutput new];
      //输出的类 为 AVCaptureMetadataOutput
        [self.session addOutput:self.metadataOutput];
        self.metadataOutput.metadataObjectTypes = @[
                                                    AVMetadataObjectTypeQRCode,
                                                    ];
        [self.metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
    
    //可以通过设置 rectOfInterest 属性,来调整扫码区域。
    

    自定义相机

        self.photoOutput = [[AVCapturePhotoOutput alloc] init];
      //输出的类 为 AVCapturePhotoOutput
        NSDictionary *setDic = @{
                                 AVVideoCodecKey:AVVideoCodecTypeJPEG,
                                 };
        self.photoSettings = [AVCapturePhotoSettings photoSettingsWithFormat:setDic];
        [self.photoOutput setPhotoSettingsForSceneMonitoring:self.photoSettings];
        [self.session addOutput:self.photoOutput];
    
    //可以通过设置 rectOfInterest 属性,来调整扫码区域。
    

    具体实现如下:

    首先,添加如下属性

    @interface XXXCaptureViewController ()<AVCaptureMetadataOutputObjectsDelegate,AVCapturePhotoCaptureDelegate>
    
    @property (nonatomic, assign)BOOL currentAuthStatus;
    
    @property (nonatomic, strong)AVCaptureDevice *device;
    @property (nonatomic, strong)AVCaptureSession *session;
    @property (nonatomic, strong)AVCaptureDeviceInput *input;
    @property (nonatomic, strong)AVCaptureMetadataOutput *metadataOutput;
    @property (nonatomic, strong)AVCapturePhotoOutput *photoOutput;
    @property (nonatomic, strong)AVCapturePhotoSettings *photoSettings;
    
    @property (nonatomic, strong)UIButton *takephotoButton;
    

    在使用相机前,要查看是否授权

    - (BOOL)authStatus
    {
        AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
        
        if (authStatus == AVAuthorizationStatusAuthorized)
        {
            return YES;
        }
        else
        {
            return NO;
        }
    }
    

    如果该 App 没有授权相机功能,需要请求授权

    __block typeof(self) weakSelf = self;
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            
            if (granted == NO)
            {
                weakSelf.currentAuthStatus = NO;
            }
            else
            {
                weakSelf.currentAuthStatus = YES;
                
                [weakSelf configureCaptureSessionSettting];
            }
    

    然后添加属性的相关设置

    - (void)configureCaptureSessionSettting
    {
        if (self.currentAuthStatus == NO)
        {
            return;
        }
        
        self.session = [AVCaptureSession new];
        self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        NSError *error;
        self.input = [AVCaptureDeviceInput  deviceInputWithDevice:self.device error:&error];
        
        [self.session addInput:self.input];
        
    //扫二维码
    //    [self.session addOutput:self.metadataOutput];
    //    self.metadataOutput.metadataObjectTypes = @[
    //                                                AVMetadataObjectTypeQRCode,//可以添加 AVMetadataObjectTypeCode39Code 等类型同时扫描条形码
    //                                                ];
    //    [self.metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
        
      //捕获照片
        self.photoOutput = [[AVCapturePhotoOutput alloc] init];
        NSDictionary *setDic = @{
                                 AVVideoCodecKey:AVVideoCodecTypeJPEG,
                                 };
        self.photoSettings = [AVCapturePhotoSettings photoSettingsWithFormat:setDic];
        [self.photoOutput setPhotoSettingsForSceneMonitoring:self.photoSettings];
        [self.session addOutput:self.photoOutput];
        
        
        AVCaptureVideoPreviewLayer* previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
            [previewLayer setFrame:self.view.bounds];
            [self.view.layer insertSublayer:previewLayer atIndex:0];
        });
       
        
    }
    
    

    最后一步啦,开始捕获数据和停止补货。最好不要把它们放在主线程中使用。因为 startRunning 和 stopRunning 其实是一个 block,主线程调用可能会引起,UI卡顿。苹果官方具体解释:https://developer.apple.com/documentation/avfoundation/avcapturesession

    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
            [self.session startRunning];
        });
    
    }
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
        
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
            [self.session stopRunning];
        });
    }
    

    相关文章

      网友评论

          本文标题:iOS 原生扫码二维码与自定义相机

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