1. 程式人生 > >自定義身份證識別相機UI

自定義身份證識別相機UI

現在很多的專案都有身份證識別的環節,而系統的相機有時不能滿足我們的需要,身份證的識別,有時需要對圖片銳化,灰值,這時對於獲取圖片的尺寸 有為重要,網上很多廠商的SDK 都會把UI這個快 封裝起來。我自定義一套希望對你們有用。

建立一個工程這裡就不多說了 一樣的套路

建立一個類

ImagePickerMamanger.h 

#import <Foundation/Foundation.h>

@interface ImagePickerMamanger : NSObject

+ (ImagePickerMamanger *)sharedInstance;

#pragma mark - 照片

/**
 *  @brief  從UIActionSheet中選擇
 *
 *  @param vc          presentVC
 *  @param block       成功回撥
 *  @param cancelBlock 取消回撥
 */
- (void)cameraSheetInController:(UIViewController *)vc   sourceView:(UIView *)view handler:(void (^)(UIImage *image))block cancelHandler:(void (^)(void))cancelBlock;


@end

ImagePickerMamanger.m

#define IS_IOS_8_OR_LATER [[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0

//螢幕寬
#define IMAGEPICKER_SCREEN_WIDTH  [[UIScreen mainScreen] bounds].size.width
//螢幕高
#define IMAGEPICKER_SCREEN_HEIGHT  [[UIScreen mainScreen] bounds].size.height

#define  IMAGEPICKER_SIZE 300

@interface ImagePickerMamanger()<UIImagePickerControllerDelegate, UINavigationControllerDelegate,UIActionSheetDelegate>

@property(nonatomic, strong) UIViewController *vc;

@property(nonatomic, strong) UIImagePickerController *imagePickerController;

@property(nonatomic,strong)UIPopoverController  * popoverController;

@property(nonatomic, strong) void (^resultBlock)(UIImage *image);

@property(nonatomic, strong) void (^cancelBlock)(void);

@end

@implementation ImagePickerMamanger

static ImagePickerMamanger *sharedInstance = nil;
#pragma mark Singleton Model
+ (ImagePickerMamanger *)sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[ImagePickerMamanger alloc]init];
        sharedInstance.imagePickerController = [[UIImagePickerController alloc]init];
        sharedInstance.imagePickerController.delegate = sharedInstance;
        if (IS_IOS_8_OR_LATER) {
            sharedInstance.imagePickerController.modalPresentationStyle = UIModalPresentationOverFullScreen;
        }
    });
    return sharedInstance;
}

#pragma mark - public methods
- (void)cameraSheetInController:(UIViewController *)vc sourceView:(UIView *)view handler:(void (^)(UIImage *))block cancelHandler:(void (^)(void))cancelBlock{
    
    self.vc = vc;
    
    self.resultBlock = block;
    self.cancelBlock = cancelBlock;
    
    if (IS_IOS_8_OR_LATER) {
        UIAlertController * alterController = [UIAlertController alertControllerWithTitle:@"選擇影象" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
        
        // 判斷是否支援相機
        if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
            
            UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
                
                [alterController dismissViewControllerAnimated:YES completion:^(void){
                    self.cancelBlock();
                }];
            }];
            
            UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
                [self openCamera:UIImagePickerControllerSourceTypeCamera];
            }];
            
            UIAlertAction *archiveAction = [UIAlertAction actionWithTitle:@"相簿選取" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                [self openCamera:UIImagePickerControllerSourceTypePhotoLibrary];
            }];
            
            [alterController addAction:deleteAction];
            [alterController addAction:archiveAction];
            [alterController addAction:cancelAction];
            
        }
        else {
            
            UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
                
                [alterController dismissViewControllerAnimated:YES completion:^(void){
                    self.cancelBlock();
                }];
            }];
            
            UIAlertAction *archiveAction = [UIAlertAction actionWithTitle:@"相簿選取" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                [self openCamera:UIImagePickerControllerSourceTypePhotoLibrary];
            }];
            
            [alterController addAction:archiveAction];
            [alterController addAction:cancelAction];
            
        }
        
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
            alterController.modalPresentationStyle = UIModalPresentationPopover;
            alterController.popoverPresentationController.sourceView = view;
            
            alterController.popoverPresentationController.sourceRect = view.bounds;
        }
        [self.vc presentViewController:alterController animated:YES completion:nil];
    }
    else{
        // 判斷是否支援相機
        if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
            
            UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"從相簿選擇",@"拍照", nil];
            sheet.tag =100;
            [sheet showInView:vc.view];

        }else{
            UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"從相簿選擇", nil];
            sheet.tag =101;
            [sheet showInView:vc.view];
        }
    }
}

#pragma mark - UIImagePickerControllerDelegate

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    // 照片
    [picker dismissViewControllerAnimated:YES completion:^{}];
    
    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
    self.resultBlock(image);
    [self.vc setNeedsStatusBarAppearanceUpdate];

};

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    self.cancelBlock();
    [self.vc setNeedsStatusBarAppearanceUpdate];
    [self.vc dismissViewControllerAnimated:YES completion:^{
    }];
}

-(void)imageWithPhotoInController:(UIViewController *)vc sourceView:(UIView *)view handler:(void (^)(UIImage *))block cancelHandler:(void (^)(void))cancelBlock{
    
    self.vc = vc;
    self.resultBlock = block;
    self.cancelBlock = cancelBlock;
    
    [self openCamera:UIImagePickerControllerSourceTypePhotoLibrary];
}

-(void)openCamera:(UIImagePickerControllerSourceType) souceType{
    // 跳轉到相機
    self.imagePickerController.sourceType = souceType;
    
    dispatch_async(dispatch_get_main_queue(), ^{
        
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
            
            if (IS_IOS_8_OR_LATER) {
                [self.vc presentViewController:self.imagePickerController animated:YES completion:^{}];
            }else{
               
                UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:self.imagePickerController];
                
                self.popoverController = popover;
                
                [self.popoverController presentPopoverFromRect:CGRectMake((IMAGEPICKER_SCREEN_WIDTH - IMAGEPICKER_SIZE)/2, (IMAGEPICKER_SCREEN_HEIGHT - IMAGEPICKER_SIZE)/2, IMAGEPICKER_SIZE, IMAGEPICKER_SIZE) inView:self.vc.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
            }
        }
        else{
            [self.vc presentViewController:self.imagePickerController animated:YES completion:^{}];
        }
        [self performSelector:@selector(delayHideStatusBar) withObject:nil afterDelay:0.5f];
    });
}

-(void)delayHideStatusBar{
    [self.vc setNeedsStatusBarAppearanceUpdate];
}

#pragma mark - UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
   
    if (actionSheet.tag == 101) {
        if (buttonIndex == 0) {
            // 跳轉到相機
            [self openCamera:UIImagePickerControllerSourceTypePhotoLibrary];
        }
       else if (buttonIndex == 1) {
            // 取消
            [self.vc dismissViewControllerAnimated:YES completion:^{
                self.cancelBlock();
            }];
        }
    }else{
        if (buttonIndex == 0) {
            // 跳轉到相機
            [self openCamera:UIImagePickerControllerSourceTypePhotoLibrary];
        }
        else if (buttonIndex == 1) {
            
            // 跳轉到相簿頁面
            [self openCamera:UIImagePickerControllerSourceTypeCamera];
        }
       else if (buttonIndex == 2) {
            // 取消
           [self.vc dismissViewControllerAnimated:YES completion:^{
               self.cancelBlock();
            }];
        }
    }
}

@end
這個類用來管理相機的開啟 拍攝成功後回撥。


在建一個類 

CWPhotoController.h

#import <UIKit/UIKit.h>

@protocol CWPhotoControllerDelegate <NSObject>

- (void)cwAutoTakePhoto:(UIImage *)image;

@end

@interface CWPhotoGraphController : UIViewController

@property(nonatomic,assign)BOOL   isFront;

@property(nonatomic,assign)id<CWPhotoControllerDelegate> delegate;

@end

CWPhotoGraphController.m

#import "CWPhotoGraphController.h"
#import <AVFoundation/AVFoundation.h>

@interface CWPhotoGraphController ()<AVCaptureMetadataOutputObjectsDelegate,UIAlertViewDelegate>
{
    
    UILabel   * label;
    
    UIImageView * imageView;
    
    CGRect     idCardRect;
    
    UIImageView  * _focusView;
}

//捕獲裝置,通常是前置攝像頭,後置攝像頭,麥克風(音訊輸入)
@property(nonatomic)AVCaptureDevice *device;

//AVCaptureDeviceInput 代表輸入裝置,他使用AVCaptureDevice 來初始化
@property(nonatomic)AVCaptureDeviceInput *input;

//當啟動攝像頭開始捕獲輸入
@property(nonatomic)AVCaptureMetadataOutput *output;

@property (nonatomic)AVCaptureStillImageOutput *ImageOutPut;

//session:由他把輸入輸出結合在一起,並開始啟動捕獲裝置(攝像頭)
@property(nonatomic)AVCaptureSession *session;

//影象預覽層,實時顯示捕獲的影象
@property(nonatomic)AVCaptureVideoPreviewLayer *previewLayer;

@property (nonatomic)UIButton *flashButton;

@property (nonatomic)BOOL isflashOn;

@property(nonatomic,strong)UIImage * image;

@end

#define kScreenWidth  [UIScreen mainScreen].bounds.size.width

#define kScreenHeight [UIScreen mainScreen].bounds.size.height

#define HeadViewHight 40

#define IDCardORigionY 30

#define ClearBoxWidth (kScreenWidth- HeadViewHight - 20)

#define ClearBoxHeight (kScreenHeight- IDCardORigionY - 100)
#define photoButtonWidth 60

@implementation CWPhotoGraphController

#pragma mark
#pragma mark----------- viewWillAppear viewWillAppear

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    if (self.navigationController != nil) {
        self.navigationController.navigationBarHidden = YES;
    }
}

#pragma mark
#pragma mark----------- viewDidLoad viewDidLoad
- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    _focusView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 60, 80)];
    _focusView.backgroundColor = [UIColor clearColor];
    _focusView.image = [UIImage imageNamed:@"focs"];
    [self.view addSubview:_focusView];
    _focusView.hidden = YES;
    //_isFront = NO;
    /**
     *  @brief 相機許可權
     */
    BOOL canOpenCamera = [self canUserCamear];
    
    if (canOpenCamera) {
        //自定義相機
        [self customCamera];
        //自定義相機顯示View
        [self custCameraView];
    }else{
        return;
    }
}

#pragma mark
#pragma mark ------------ canUserCamear 檢查相機許可權
- (BOOL)canUserCamear{
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    
    if (authStatus == AVAuthorizationStatusDenied) {
        
        UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"請開啟相機許可權" message:@"設定-隱私-相機" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:@"取消", nil];
        alertView.tag = 100;
        [alertView show];
        return NO;
    }
    else{
        return YES;
    }
    return YES;
}

#pragma mark
#pragma mark ------------ clickedButtonAtIndex alterView代理方法
/**
 *  @brief alterView代理方法
 *
 *  @param alertView   alertView
 *  @param buttonIndex 按鈕索引
 */

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    if (buttonIndex == 0 && alertView.tag == 100) {
        NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        
        if([[UIApplication sharedApplication] canOpenURL:url]) {
            
            [[UIApplication sharedApplication] openURL:url];
        }
    }
}

#pragma mark
#pragma mark----------- custCameraView 相機介面
/**
 *  @brief 相機介面
 */
-(void)custCameraView{
    
    /**
     半透明背景
     */
    imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight)];
    [self.view addSubview:imageView];
    
    imageView.backgroundColor = [UIColor clearColor];
    
    imageView.userInteractionEnabled = YES;

    /**
     身份證對齊框
     */
    idCardRect = CGRectMake(HeadViewHight, IDCardORigionY, ClearBoxWidth, ClearBoxHeight);
    
    if(IS_IPAD){
        idCardRect = CGRectMake(100, 100, (kScreenWidth- 220), (kScreenHeight- 300));
    }

    /**
     畫中間透明周圍半透明的圖
     */
    UIImage * image = [self drawImage:imageView.frame AndClearRect:idCardRect];
    
    imageView.image = image;
    
    UIImageView * centerImageView = [[UIImageView alloc]initWithFrame:idCardRect];
    
    centerImageView.backgroundColor = [UIColor clearColor];
    
    centerImageView.userInteractionEnabled = YES;
    
    //身份證正反面圖
    if (self.isFront) {
        centerImageView.image = [UIImage imageNamed:@"frontBox"];
    }else{
        centerImageView.image = [UIImage imageNamed:@"backBox"];
    }
    [self.view addSubview:centerImageView];

    /**
     文字提示Label
     */
    if (IS_IPAD) {
        label = [[UILabel alloc]initWithFrame:CGRectMake(-(kScreenWidth-80)/2, (kScreenHeight-100)/2, kScreenHeight-200, 40)];
    }else{
        if (kScreenHeight<568) {
            label = [[UILabel alloc]initWithFrame:CGRectMake(-125, 220,kScreenHeight-200, 40)];
        }else if(kScreenHeight == 667){
            label = [[UILabel alloc]initWithFrame:CGRectMake(-210, 250, kScreenHeight-200, 40)];
        }else if(kScreenHeight >= 736){
            label = [[UILabel alloc]initWithFrame:CGRectMake(-245, 280, kScreenHeight-200, 40)];
        }else{
            label = [[UILabel alloc]initWithFrame:CGRectMake(-165, 230, kScreenHeight-200, 40)];
        }
    }
    
    label.textAlignment = NSTextAlignmentCenter;
    label.backgroundColor = [UIColor clearColor];
    label.textColor = [UIColor whiteColor];
    label.font =[UIFont boldSystemFontOfSize:17.f];
    label.text = @"請橫握手機拍照,並將身份證置於框內";
    //順時針旋轉90度
    label.transform = CGAffineTransformMakeRotation( M_PI/2 );
    [self.view addSubview:label];

    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(focusGesture:)];
    
    [centerImageView addGestureRecognizer:tapGesture];
    
    /**
     *  @brief 拍照按鈕
     */
    UIButton * photoButton = [UIButton buttonWithType:UIButtonTypeCustom];
    photoButton.frame = CGRectMake((kScreenWidth-photoButtonWidth)/2+20, (kScreenHeight-photoButtonWidth-20), photoButtonWidth, photoButtonWidth);
    
    [photoButton setImage:[UIImage imageNamed:@"paizhao1"] forState:UIControlStateNormal];
    
    [self.view addSubview:photoButton];
    
    [self.view bringSubviewToFront:photoButton];
    
    [photoButton addTarget:self action:@selector(takePhoto) forControlEvents:UIControlEventTouchUpInside];
    
    /**
     *  @brief 返回按鈕
     */
    UIButton * backButton = [UIButton buttonWithType:UIButtonTypeCustom];
    backButton.frame = CGRectMake(20, (kScreenHeight-photoButtonWidth-20), 60, 60);
    [backButton setImage:[UIImage imageNamed:@"fanhui1"] forState:UIControlStateNormal];
    [self.view addSubview:backButton];
    [backButton addTarget:self action:@selector(dismissViewController) forControlEvents:UIControlEventTouchUpInside];
    
    self.flashButton = [UIButton buttonWithType:UIButtonTypeCustom];
    self.flashButton.frame = CGRectMake(kScreenWidth-50, (kScreenHeight-photoButtonWidth-20), 30, 30);
    [ self.flashButton setImage:[UIImage imageNamed:@"camera-flash-off"] forState:UIControlStateNormal];
   
    [self.flashButton addTarget:self action:@selector(FlashOn) forControlEvents:UIControlEventTouchUpInside];
     //[self.view addSubview:self.flashButton];
    
    
}

- (void)focusGesture:(UITapGestureRecognizer*)gesture{
    CGPoint point = [gesture locationInView:gesture.view];
    [self focusAtPoint:point];
}
#pragma mark
#pragma mark----------- customCamera 自定義相機
/**
 *  @brief 自定義相機
 */
- (void)customCamera{
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    //使用AVMediaTypeVideo 指明self.device代表視訊,預設使用後置攝像頭進行初始化
    self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    //使用裝置初始化輸入
    self.input = [[AVCaptureDeviceInput alloc]initWithDevice:self.device error:nil];
    
    //生成輸出物件
    self.output = [[AVCaptureMetadataOutput alloc]init];
    
    self.ImageOutPut = [[AVCaptureStillImageOutput alloc] init];
    
    NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];

    self.ImageOutPut.outputSettings = outputSettings;

    //生成會話,用來結合輸入輸出
    self.session = [[AVCaptureSession alloc]init];
    if ([self.session canSetSessionPreset:AVCaptureSessionPreset1280x720]) {
        self.session.sessionPreset = AVCaptureSessionPreset1280x720;
    }
    
    if ([self.session canAddInput:self.input]) {
        [self.session addInput:self.input];
    }
    
    if ([self.session canAddOutput:self.ImageOutPut]) {
        [self.session addOutput:self.ImageOutPut];
    }
    
    //使用self.session,初始化預覽層,self.session負責驅動input進行資訊的採集,layer負責把影象渲染顯示
    self.previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session];
    
    self.previewLayer.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
    
    self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    
    [self.view.layer addSublayer:self.previewLayer];
    
    //開始啟動
    [self.session startRunning];
    
    if ([_device lockForConfiguration:nil]) {
        if ([_device isFlashModeSupported:AVCaptureFlashModeAuto]) {
            [_device setFlashMode:AVCaptureFlashModeAuto];
        }
        //自動白平衡
        if ([_device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeAutoWhiteBalance]) {
            [_device setWhiteBalanceMode:AVCaptureWhiteBalanceModeAutoWhiteBalance];
        }
        [_device unlockForConfiguration];
    }
    
   AVCaptureConnection  *  _videoConnection = [self.output connectionWithMediaType:AVMediaTypeVideo];
    UIDeviceOrientation _camraOrientaion = [[UIDevice currentDevice] orientation];
    if (_videoConnection.supportsVideoOrientation ) {
        switch (_camraOrientaion) {
            case UIDeviceOrientationPortrait:
                _videoConnection.videoOrientation = AVCaptureVideoOrientationPortrait;
                break;
            case UIDeviceOrientationPortraitUpsideDown:
                _videoConnection.videoOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
                break;
            case UIDeviceOrientationLandscapeLeft:
                _videoConnection.videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
                break;
            case UIDeviceOrientationLandscapeRight:
                _videoConnection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
                break;
            default:
                break;
        }
    }
}

#pragma mark
#pragma mark----------- cameraWithPosition 獲取相機裝置
/**
 *  @brief  獲取相機
 *
 *  @param position 相機型別、前置還是後置相機
 *
 *  @return 相機device
 */
- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition)position{
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for ( AVCaptureDevice *device in devices )
        if ( device.position == position ) return device;
    return nil;
}

#pragma mark
#pragma mark----------- FlashOn 開啟或者關閉閃光燈
/**
 *  @brief 開啟或者關閉閃光燈
 */
- (void)FlashOn{
    
    if ([_device lockForConfiguration:nil]) {
        /**
         *  @brief 關閉閃光燈
         */
        if (_isflashOn) {
            if ([_device isFlashModeSupported:AVCaptureFlashModeOff]) {
                [_device setFlashMode:AVCaptureFlashModeOff];
                _isflashOn = NO;
                [_flashButton setImage:[UIImage imageNamed:@"camera-flash-off"] forState:UIControlStateNormal];
            }
        }else{
            /**
             *  @brief 開啟閃光燈
             */
            if ([_device isFlashModeSupported:AVCaptureFlashModeOn]) {
                [_device setFlashMode:AVCaptureFlashModeOn];
                _isflashOn = YES;
                [_flashButton setImage:[UIImage imageNamed:@"camera-flash-on"] forState:UIControlStateNormal];
            }
        }
        [_device unlockForConfiguration];
    }
}

#pragma mark
#pragma mark----------- focusAtPoint 相機對焦
- (void)focusAtPoint:(CGPoint)point{
    CGSize size = self.view.bounds.size;
//    CGPoint point = CGPointMake(kScreenWidth/2, kScreenHeight/2);
    CGPoint focusPoint = CGPointMake( point.y /size.height ,1-point.x/size.width );
    NSError *error;
    if ([self.device lockForConfiguration:&error]) {
        
        if ([self.device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
            [self.device setFocusPointOfInterest:focusPoint];
            [self.device setFocusMode:AVCaptureFocusModeAutoFocus];
        }
        
        if ([self.device isExposureModeSupported:AVCaptureExposureModeAutoExpose ]) {
            [self.device setExposurePointOfInterest:focusPoint];
            [self.device setExposureMode:AVCaptureExposureModeAutoExpose];
        }
        
        _focusView.center = point;
        
        _focusView.hidden = NO;
        
        [self.view bringSubviewToFront:_focusView];
        
        [UIView animateWithDuration:0.3 animations:^{
            _focusView.transform = CGAffineTransformMakeScale(1.1, 1.1);
        }completion:^(BOOL finished) {
            [UIView animateWithDuration:0.5 animations:^{
                _focusView.transform = CGAffineTransformIdentity;
            } completion:^(BOOL finished) {
                _focusView.hidden = YES;
            }];
        }];

        [self.device unlockForConfiguration];
    }
}

#pragma mark
#pragma mark--------------- takePhoto 拍攝照片

- (void)takePhoto
{
    AVCaptureConnection * videoConnection = [self.ImageOutPut connectionWithMediaType:AVMediaTypeVideo];
    
    if (!videoConnection) {
        NSLog(@"take photo failed!");
        return;
    }

    [self.ImageOutPut captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
        
        if (imageDataSampleBuffer == NULL) {
            return;
        }

        NSData * imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
        
        UIImage  * image = [UIImage imageWithData:imageData];
        NSInteger card= [[CloudwalkFaceSDK shareInstance] cwIDCardInit:AuthCodeString];
        
[self sendPhotoControllerDelegate:image];
}/** * @brief 拍照後的圖片代理方法 * * @param idImage 拍攝的照片 */-(void)sendPhotoControllerDelegate:(UIImage *)idImage{ if (self.delegate != nil && [self.delegate respondsToSelector:@selector(cwAutoTakePhoto:)]) { [self.delegate cwAutoTakePhoto:idImage]; } dispatch_async(dispatch_get_main_queue(), ^{ [self dismissViewController]; });}#pragma mark#pragma mark----------- dismissViewController 關閉介面-(void)dismissViewController{ // [[CloudwalkFaceSDK shareInstance] cwDestroy]; //關閉相機介面 [self.session stopRunning]; if (self.navigationController != nil) { [self.navigationController popViewControllerAnimated:YES]; }else [self dismissViewControllerAnimated:YES completion:^{}];}#pragma mark#pragma mark-----------drawImage //畫中間透明的圖片-(UIImage *)drawImage:(CGRect)BgRect AndClearRect:(CGRect)ClearRect{ CGSize screenSize =[UIScreen mainScreen].bounds.size; UIGraphicsBeginImageContext(BgRect.size); CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextSetRGBFillColor(ctx, 0,0,0,0.5); CGRect drawRect =CGRectMake(0, 0, screenSize.width,screenSize.height); CGContextFillRect(ctx, drawRect); CGContextClearRect(ctx, ClearRect); //clear the center rect of the layer UIImage* returnimage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return returnimage;}- (BOOL)prefersStatusBarHidden{ return YES;}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}/*#pragma mark - Navigation// In a storyboard-based application, you will often want to do a little preparation before navigation- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller.}*/@end 最後附上很類似的demo GitHub地址  https://github.com/wjx1018960145/Resource.git  

相關推薦

定義身份證識別相機UI

現在很多的專案都有身份證識別的環節,而系統的相機有時不能滿足我們的需要,身份證的識別,有時需要對圖片銳化,灰值,這時對於獲取圖片的尺寸 有為重要,網上很多廠商的SDK 都會把UI這個快 封裝起來。我自定義一套希望對你們有用。建立一個工程這裡就不多說了 一樣的套路建立一個類

發票識別----增值稅專,普發票識別定義票據識別,機動車銷售發票識別

關鍵詞:增值稅專用發票掃描識別,機動車銷售發票掃描識別 產品概述 增值稅專用發票掃描識別系統L7280+(簡稱快票通L7280+)是一款針對增值稅專用發票以及常見的表單、票據等紙質文件資料掃描識別的產品,利用OCR識別技術,對增值稅專用發票掃描識別,快速完成表單、票據的資訊採集。 快票通

android定義底部Tab導航UI,專案整體介面框架

android自定義底部Tab導航UI,專案整體介面框架 共享一個自己在開發過程中搭建的android專案介面框架,便於提高開發效率。 主要功能 1.使用Button自定義底部Tab和Title 2.點選底部Tab後使用Fragment切換頁面 3.主頁使用ViewPager滾動

vue 定義 數字鍵盤+mint UI MessageBox的應用

功能: 實現自定義數字鍵盤,輸入數字超過兩位時不可輸入 點選清空清空輸入框內的值 提交時彈出提示框,並顯示所輸入的數字用--mint UI實現 效果圖: <div class="number">

Qt定義控制元件大全+UI定製+輸入法

做各種各樣的介面的時候,經常需要做一排按鈕用於切換到對應介面,俗稱導航按鈕或者導航選單,參照過各種各樣的主介面導航佈局,特意編寫導航按鈕自定義控制元件,結合各種情況,繼承自QPushButton。已整合在QUC自定義控制元件中。 /** * 導航按鈕控制元件 作者:f

Android-定義手勢識別-複雜手勢識別

一、概述 1、手勢互動過程(原理) (1)觸屏一剎那,觸發MotionEvent事件 (2)被OnTounchListener監聽,在onTouch()中獲得MotionEvent物件 (3)GestureDetector轉發MotionEvent物件至OnGestureL

Android 拍身份證定義相機

Android自定義相機拍攝二代身份證。 感謝開源,尊重他人勞動成果,本自定義相機拍照核心邏輯取自雲棲社群上Android 手把手帶你玩轉自定義相機 文章,本文僅僅在此基礎上再次封裝了返回拍照地址等監聽事件,另外拍攝按鈕沒有做動畫效果(待優化) 佈局檔

iOS人臉識別定義相機、影象掃描、系統帶二維碼識別

前段時間遇到一個需求,需要實時掃描影象,並且設定攝像頭的尺寸為1080x1920,然後從中間截取出512x512的圖片傳給第三方SDK做進一步業務處理,直到SDK返回正確的處理結果。 一頓Google,發現影象預覽、人臉識別、二維碼識別這些蘋果都幫我們做好了,而且它們都是基

jQuery基礎(常用插件 表單驗證,圖片放大鏡,定義對象級,jQuery UI,面板折疊)

此外 cookie值 添加圖標 tor 列表 需要 droppable 使用 ddn 1.表單驗證插件——validate 該插件自帶包含必填、數字、URL在內容的驗證規則,即時顯示異常信息,此外,還允許自定義驗證規則,插件調用方法如下: $(form).vali

Android定義相機超詳細講解

了解 catch 實現 4.4 required form 需要 eset 自己 Android自定義相機超詳細講解 轉載請標明出處: http://blog.csdn.net/vinicolor/article/details/49642861; 由於網上關於Andr

在Unity3D項目中接入ShareSDK實現安卓平臺微信分享功能(可使用ShareSDK默認UI定義UI

顯示 選項 dev template 腳本 配置文件 all 自己 show   最近公司的大廳要重做,我協助主程一起制作新大廳和新框架,前面制作的編輯器也派上了用場。等全部功能做完後我會再寫一個復盤,這兩天主程在忙於寫熱更新的功能,所以把接入分享SDK功能的任務交給了我,

android用camera2api定義相機

stream javaweb asp ner servle android avast andro 自定義 js%E5%9F%BA%E7%A1%80%E4%BD%9C%E7%94%A8%E5%9F%9F%E5%92%8C%E9%97%AD%E5%8C%85 javastr

iOS開發筆記17:定義相機拍照

hub 銷毀 用戶 做了 api 交互設計 cap iphone 結果 之前用AVFoundation自定義相機做了拍照與視頻相關的東西,為什麽要自定義呢?主要是提供更個性化的交互設計,符合app主題,對於視頻來說,也便於提供更多豐富有趣的功能。前段時間整理了下拍照部分的功

Idea_學習_03_IDEA中使定義類型的文件進行代碼高亮識別

segment tar register 定義 類型 自定義類 pos edi ref 如果你只是想用xml的編輯模式來編輯*.screen文件的話,可以在 Settings->Editor->File Types 中,在Recognized File Ty

一種不通過UI給C4C定義BO創建測試數據的方式

sdl http mage 得到 order studio 兩個 strip test 假設我在Cloud Studio裏創建了如下一個非常簡單的自定義BO: 我想生成一些該BO的實例。以前我采用的做法是給這個自定義BO創建編輯用的UI。然後使用這些UI創建BO實例。這種

定義element-ui主題,修改樣式

改版 引入 一個 css template div 應用 根據 得到 項目需求 之前項目中引用的select選框有bug,所以需要改動,考慮到還有許多需求,果斷將餓了麽組件全移過來 安裝element-ui2.0.1版本 安裝完之後,我就將element-ui的組件應用上,

vue Element-ui 表格帶篩選框定義高度

image n-k pre chrome code lac 分享 sso spa el-table中可以在一行的某列進行篩選,代碼如下: <el-table-column prop="classOfTest" class="test" label="測試類名" :

[python]RobotFramework定義庫實現UI自動化

bubuko output source 自動 封裝 9.png 全局變量 詳細 變量 1.安裝教程 環境搭建不多說,網上資料一大堆,可參考https://www.cnblogs.com/puresoul/p/3854963.html,寫的比較詳細,值得推薦。目前pyt

Element-ui tree組件定義節點使用方法

置頂 add text rop sign del let 1-1 fault 工作上使用到element-ui tree 組件,主要功能是要實現節點拖拽和置頂,通過自定義內容方法(render-content)渲染樹代碼如下~ 1 <template>

React學習之旅----按需載入Antd UI元件及定義主題

package.json "babel": { "presets": [ "react-app" ], "plugins": [ [ "import", { "libraryName": "a