DFCaptureController介绍

1. DFCaptureControllerDelegate协议

/// 检测句柄初始化回调
/// @param errorCode 错误码
- (void)initCompletedWithErrorCode:(int)errorCode;
/// 检测成功回调
/// @param image 检测到的卡证图片
/// @param cardSideType 卡证类型
/// @param isCopy 是否是复印件
- (void)detectFinished:(UIImage *)image cardSideType:(DFCardDetectedSide)cardSideType isCopy:(BOOL)isCopy;
/// 开启自动上传识别,识别成功回调
/// @param image 检测到的卡证图片
/// @param cardSideType 卡证类型
/// @param isCopy 是否是复印件
/// @param result 识别结果
- (void)recognizeSucessfully:(UIImage *)image cardSideType:(DFCardDetectedSide)cardSideType isCopy:(BOOL)isCopy result:(NSDictionary *)result;
/// 开启自动上传识别,识别失败回调
/// @param image 检测到的卡证图片
/// @param cardSideType 卡证类型
/// @param isCopy 是否是复印件
/// @param errorMessage 错误信息
- (void)recognizeFailed:(UIImage *)image cardSideType:(DFCardDetectedSide)cardSideType isCopy:(BOOL)isCopy errorMessage:(NSString *)errorMessage;

2.初始化

/// 检测页面初始化
/// @param cardType 卡证类型
/// @param filterCopy 是否过滤复印件
/// @param delegate 代理
/// @param autoRecognize 是否自动上传识别
/// @param navigationController 导航控制器
+ (instancetype)pushCaptureControllerWithCardType:(DFCardDetectedType)cardType
                                       filterCopy:(BOOL)filterCopy
                                         delegate:(id<DFCaptureControllerDelegate>)delegate
                                    autoRecognize:(BOOL)autoRecognize
                             navigationController:(UINavigationController *)navigationController;

3.自定义相机

- (AVCaptureVideoPreviewLayer *)previewLayer
{
    if (_previewLayer == nil) {
        _previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
        _previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    }
    return _previewLayer;
}
- (AVCaptureDevice *)device
{
    if (_device == nil) {
        _device = [self cameraWithPosition:AVCaptureDevicePositionBack];
        if ([_device lockForConfiguration:nil]) {
            //自动闪光灯
            if ([_device isFlashModeSupported:AVCaptureFlashModeAuto]) {
                [_device setFlashMode:AVCaptureFlashModeAuto];
            }
            //自动白平衡
            if ([_device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]) {
                [_device setWhiteBalanceMode:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance];
            }
            //自动对焦
            if ([_device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
                [_device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
            }
            //自动曝光
            if ([_device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
                [_device setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
            }

            int frameRate = 30;
            CMTime frameDuration = kCMTimeInvalid;
            frameDuration = CMTimeMake(1, frameRate);
            _device.activeVideoMaxFrameDuration = frameDuration;
            _device.activeVideoMinFrameDuration = frameDuration;

            [_device unlockForConfiguration];
        }
    }
    return _device;
}
- (AVCaptureDeviceInput *)input
{
    if (_input == nil) {
        _input = [[AVCaptureDeviceInput alloc] initWithDevice:self.device error:nil];
    }
    return _input;
}
- (AVCaptureVideoDataOutput *)videoDataOutput
{
    if (_videoDataOutput == nil) {
        _videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
        [_videoDataOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
    }
    return _videoDataOutput;
}
- (AVCaptureSession *)session
{
    if (_session == nil) {
        _session = [[AVCaptureSession alloc] init];

        if ([_session canAddInput:self.input]) {
            [_session addInput:self.input];
        }

        if ([_session canAddOutput:self.videoDataOutput]) {
            [_session addOutput:self.videoDataOutput];
        }
        if ([_session canSetSessionPreset:AVCaptureSessionPreset1280x720]) {
            _session.sessionPreset = AVCaptureSessionPreset1280x720;
        }
    }
    return _session;
}
- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition)position
{
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in devices)
        if (device.position == position) {
            return device;
        }
    return nil;
}

4.UI布局添加检测区域遮罩

- (void)setupSubViews
{
    self.view.backgroundColor = [UIColor whiteColor];
    UIView *preview = [[UIView alloc] initWithFrame:self.view.bounds];
    preview.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:preview];
    self.preview = preview;

    CGRect bounds = self.preview.bounds;
    self.previewLayer.frame = bounds;
    self.previewLayer.position = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
    self.previewLayer.backgroundColor = [UIColor whiteColor].CGColor;
    [self.preview.layer addSublayer:self.previewLayer];

    if ([self.previewLayer.connection isVideoOrientationSupported]) {
        [self.previewLayer.connection setVideoOrientation:AVCaptureVideoOrientationPortrait];
    }

    CGFloat width = [UIScreen mainScreen].bounds.size.width * 0.9;
    CGFloat x = ([UIScreen mainScreen].bounds.size.width - width) / 2.0;
    CGFloat ratio = DFDETECTREGIONSCALE;

    self.windowFrame = CGRectMake(x, 232 / 2.0, width, width / ratio);

    DFCardCaptureView *captureView = [[DFCardCaptureView alloc] initWithFrame:self.preview.bounds andWindowFrame:self.windowFrame superLayer:self.previewLayer];
    self.captureView = captureView;
}

5.初始化卡证检测

- (void)setupCardsDetector
{
    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"df_cards_detector" ofType:@"bundle"];
    NSString *licensePath = [NSString stringWithFormat:@"%@/DFLicense", bundlePath];
    DFCardsDetector *detector = [[DFCardsDetector alloc] initWithResourceBundlePath:bundlePath licensePath:licensePath delegate:self];
    [detector setCardDetectedType:self.cardType filterCopy:self.filterCopy];
    self.detector = detector;
}

4.实现卡证检测代理方法

初始化回调
- (void)initCompletedWithErrorCode:(int)errorCode
{
    if (errorCode != 0) {
        [self.navigationController popViewControllerAnimated:YES];
        if (self.delegate && [self.delegate respondsToSelector:@selector(initCompletedWithErrorCode:)]) {
            [self.delegate initCompletedWithErrorCode:errorCode];
        }
    }
}
检测状态回调
- (void)detectCard:(BOOL)isDetectedCard
{
    if (isDetectedCard) {
        [self.captureView setLineColor:[UIColor greenColor]];
    } else {
        [self.captureView setLineColor:[UIColor redColor]];
    }
}
检测完成回调
- (void)detectFinished:(UIImage *)image cardSideType:(DFCardDetectedSide)cardSideType isCopy:(BOOL)isCopy
{
    [self stopScanning];
    if (self.autoRecognize) {
        __weak __typeof(self) weakSelf = self;
        DFRecognizeController *recognizeController = [[DFRecognizeController alloc] initWithImage:image cardSide:cardSideType cardType:self.cardType isCopy:isCopy successBlock:^(UIImage * _Nonnull image, DFCardDetectedSide cardSide, BOOL isCopy, NSDictionary * _Nonnull result) {
            if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(recognizeSucessfully:cardSideType:isCopy:result:)]) {
                [weakSelf.delegate recognizeSucessfully:image cardSideType:cardSideType isCopy:isCopy result:result];
            }
        } failedBlock:^(NSString * _Nonnull errorMessage) {
            if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(recognizeFailed:cardSideType:isCopy:errorMessage:)]) {
                [weakSelf.delegate recognizeFailed:image cardSideType:cardSideType isCopy:isCopy errorMessage:errorMessage];
            }
        }];
        [self addChildViewController:recognizeController];
        [self.view addSubview:recognizeController.view];
    } else {
        if (self.delegate && [self.delegate respondsToSelector:@selector(detectFinished:cardSideType:isCopy:)]) {
            [self.delegate detectFinished:image cardSideType:cardSideType isCopy:isCopy];
        }
    }
}

5.开始卡证检测

在相机回调中调用卡证检测对象的检测方法。

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
    if ([connection isVideoOrientationSupported]) {
        [connection setVideoOrientation:AVCaptureVideoOrientationPortrait];
    }
    // detect
    CGRect detectRect = self.windowFrame;
    detectRect.origin.y -= self.statusBarHeight > 0 ? 20 : 0;
    [self.detector detectWithCMSampleBuffer:sampleBuffer detectRect:detectRect previewSize:CGSizeMake(1280, 720) degree:0];
}

results matching ""

    No results matching ""