OliveappIdcardCaptorViewController.m 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. //
  2. // CameraViewController.m
  3. // DemoFanPai
  4. //
  5. // Created by Xiaoyang Lin on 16/4/22.
  6. // Copyright © 2016年 com.yitutech. All rights reserved.
  7. //
  8. #import "OliveappIdcardCaptorViewController.h"
  9. #import "OliveappCameraPreviewController.h"
  10. #import "OliveappImageForVerifyConf.h"
  11. #import "OliveappStructOcrFrameResult.h"
  12. #import "OliveappAsyncIdcardCaptorDelegate.h"
  13. #import "OliveappIdcardVerificationController.h"
  14. #import "OliveappImageUtility.h"
  15. #import <AVFoundation/AVFoundation.h>
  16. #import "OliveappDeviceHelper.h"
  17. @interface OliveappIdcardCaptorViewController () <OliveappAsyncIdcardCaptorDelegate,OliveappCameraImageCaptureDelegate>
  18. #if !TARGET_IPHONE_SIMULATOR
  19. @property (strong, nonatomic) OliveappCameraPreviewController * mCameraController;
  20. @property (strong, nonatomic) OliveappIdcardVerificationController * mIdcardVerificationController;
  21. @property (strong, nonatomic) id<OliveappIdcardCaptorResultDelegate> delegate;
  22. @property (strong, nonatomic) IBOutlet UIView *fullView;
  23. @property (weak, nonatomic) IBOutlet UIImageView *idCardLocation;
  24. @property (strong, nonatomic) IBOutlet UIView *superFullView;
  25. @property (weak, nonatomic) IBOutlet UILabel *resultLabel;
  26. @property (weak, nonatomic) IBOutlet UIButton *mImageCaptureButton;
  27. @property (strong, nonatomic) OliveappImageForVerifyConf * mOliveappImageForVerifyConf;
  28. @property (nonatomic, strong) UIImageView * mScanLineImg;
  29. @property (strong, nonatomic) NSDictionary * statusDict;
  30. @property (strong, nonatomic) NSArray * boundsArray;
  31. @property int boundsIndex;
  32. @property OliveappCardType mCardType;
  33. @property OliveappCaptureMode mCaptureMode;
  34. @property int mDurationSecond;
  35. @property (strong, nonatomic) NSTimer * mTimer;
  36. @end
  37. @implementation OliveappIdcardCaptorViewController
  38. - (void)viewDidLoad {
  39. [super viewDidLoad];
  40. //设置摄像头方向
  41. [OliveappDeviceHelper setFixedOrientation:PORTRAIT];
  42. NSLog(@"[OliveappIdcardCaptorViewController] viewDidLoad");
  43. // 调用摄像头
  44. if (_mCameraController == nil) {
  45. _mCameraController = [[OliveappCameraPreviewController alloc] init];
  46. }
  47. //初始化图片配置
  48. _mOliveappImageForVerifyConf = [[OliveappImageForVerifyConf alloc] init];
  49. //提示文字旋转90度
  50. _resultLabel.transform = CGAffineTransformMakeRotation(M_PI/2);
  51. //提示文字字典
  52. NSString * path = [[NSBundle mainBundle] pathForResource:@"OliveappOcrStatus" ofType:@"plist"];
  53. _statusDict = [NSDictionary dictionaryWithContentsOfFile:path];
  54. }
  55. - (void) viewWillAppear:(BOOL)animated {
  56. [super viewWillAppear:animated];
  57. NSLog(@"[OliveappIdcardCaptorViewController] viewWillAppear");
  58. [self.mImageCaptureButton setHidden:YES];
  59. //使用后置摄像头
  60. [_mCameraController startCamera:AVCaptureDevicePositionBack withResolution:AVCaptureSessionPresetHigh];
  61. if (_mCaptureMode == ONLY_AUTO_MODE || _mCaptureMode == MIXED_MODE) {
  62. //初始化算法模块
  63. NSError * error;
  64. _mIdcardVerificationController = [[OliveappIdcardVerificationController alloc] init];
  65. __weak typeof(self)weakSelf = self;
  66. [_mIdcardVerificationController setDelegate:weakSelf
  67. withCardType:_mCardType
  68. withError:&error];
  69. // 设置委托方法
  70. __weak typeof (OliveappIdcardVerificationController *) weakIdcardVerificationController = _mIdcardVerificationController;
  71. [_mCameraController setCameraPreviewDelegate:weakIdcardVerificationController];
  72. [_mCameraController setCameraImageCaptureDelegate:weakSelf];
  73. [_mIdcardVerificationController setIdCardPreviewView:self.idCardLocation withFullView:self.fullView withSuperView:self.superFullView];
  74. } else {
  75. NSLog(@"仅手动拍摄");
  76. __weak typeof(self) weakSelf = self;
  77. [_mCameraController setCameraImageCaptureDelegate:weakSelf];
  78. [self.mImageCaptureButton setHidden:NO];
  79. [self.resultLabel setHidden:YES];
  80. }
  81. }
  82. - (void) viewDidAppear:(BOOL)animated {
  83. //如果是混合模式,则开始计时
  84. if (_mCaptureMode == MIXED_MODE) {
  85. _mTimer = [NSTimer scheduledTimerWithTimeInterval:_mDurationSecond target:self selector:@selector(startManualMode) userInfo:nil repeats:NO];
  86. }
  87. if (_mCaptureMode == ONLY_AUTO_MODE || _mCaptureMode == MIXED_MODE) {
  88. [self startAnimation];
  89. }
  90. }
  91. /**
  92. * 在这里设置预览
  93. */
  94. - (void)viewDidLayoutSubviews {
  95. [super viewDidLayoutSubviews];
  96. NSLog(@"[OliveappIdcardCaptorViewController] viewDidLayoutSubviews");
  97. // 设置界面预览,使用全屏
  98. [_mCameraController setupPreview: _fullView];
  99. }
  100. - (void) viewWillDisappear:(BOOL)animated {
  101. [super viewWillDisappear:animated];
  102. NSLog(@"[OliveappIdcardCaptorViewController] viewWillDisappear");
  103. }
  104. - (void) viewDidDisappear:(BOOL)animated {
  105. [super viewDidDisappear:animated];
  106. NSLog(@"[OliveappIdcardCaptorViewController] viewDidDisappear");
  107. //关闭摄像头
  108. [_mCameraController stopCamera];
  109. // 析构算法模块
  110. [_mIdcardVerificationController unInit];
  111. _mIdcardVerificationController = nil;
  112. [self stopAnimation];
  113. //记得释放定时器
  114. [_mTimer invalidate];
  115. _mTimer = nil;
  116. }
  117. - (void)didReceiveMemoryWarning {
  118. [super didReceiveMemoryWarning];
  119. // Dispose of any resources that can be recreated.
  120. }
  121. - (void) onImageCapture:(OliveappPhotoImage *)image {
  122. // 预处理图片
  123. CGRect cropRect = [OliveappPhotoImage getCropWithWidth:image.imageWidth
  124. withHeight:image.imageHeight
  125. withApertureView:self.idCardLocation
  126. withCameraPreviewSuperViewAdapter:self.fullView];
  127. //切割后
  128. CIImage * croppedCIImage = [OliveappImageUtility cropImage:image.ciImage withCropArea:cropRect];
  129. image.ciImage = croppedCIImage;
  130. image.imageWidth = cropRect.size.width;
  131. image.imageHeight = cropRect.size.height;
  132. UIImage * uiimage = [OliveappImageUtility makeUIImageFromCIImage:image.ciImage];
  133. NSData * imageContent = UIImageJPEGRepresentation(uiimage, 1.0);
  134. [_delegate onDetectionSucc:imageContent];
  135. }
  136. - (void) onDetectionSucc: (NSData *) imgData {
  137. // 一定要在UI线程
  138. assert([NSThread isMainThread] == 1);
  139. [_delegate onDetectionSucc:imgData];
  140. }
  141. - (void) onDetectionStatus: (int) status {
  142. // 一定要在UI线程
  143. assert([NSThread isMainThread] == 1);
  144. NSLog(@"[OliveappIdcardCaptorViewController] onDetectionStatus: %d",status);
  145. [self.resultLabel setText:[_statusDict objectForKey:[NSString stringWithFormat:@"ocr_status_%d",status]]];
  146. }
  147. - (IBAction)captureImage:(UIButton *)sender {
  148. [_mCameraController takePhoto];
  149. }
  150. - (IBAction)cancelButton:(UIButton *)sender {
  151. // 先停止算法模块,然后退出界面
  152. [_delegate onIdcardCaptorCancel];
  153. }
  154. - (void) setDelegate: (id<OliveappIdcardCaptorResultDelegate>) delegate
  155. withCardType: (OliveappCardType) cardType
  156. withCaptureMode: (OliveappCaptureMode) captureMode
  157. withDurationSecond: (int) second {
  158. _delegate = delegate;
  159. _mCardType = cardType;
  160. _mCaptureMode = captureMode;
  161. _mDurationSecond = second;
  162. }
  163. - (void) dealloc {
  164. NSLog(@"OliveappIdcardCaptorViewController dealloc");
  165. _delegate = nil;
  166. }
  167. - (void) startManualMode {
  168. //停止算法
  169. [_mIdcardVerificationController unInit];
  170. _mIdcardVerificationController = nil;
  171. //显示按钮
  172. [_mImageCaptureButton setHidden:NO];
  173. [_resultLabel setHidden:YES];
  174. [self stopAnimation];
  175. }
  176. - (void) startAnimation {
  177. //扫描线
  178. UIImage * scanLine = [UIImage imageNamed:@"oliveapp_scan_line.png"];
  179. self.mScanLineImg = [[UIImageView alloc] initWithFrame:CGRectMake(self.idCardLocation.frame.origin.x,self.idCardLocation.frame.origin.y,scanLine.size.width,self.idCardLocation.frame.size.height)];
  180. self.mScanLineImg.image = scanLine;
  181. self.mScanLineImg.contentMode = UIViewContentModeScaleAspectFit;
  182. [self.view addSubview:self.mScanLineImg];
  183. [self.mScanLineImg.layer addAnimation:[self animation] forKey:nil];
  184. }
  185. - (CABasicAnimation *)animation{
  186. CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"position"];
  187. animation.duration = 3;
  188. animation.fillMode = kCAFillModeForwards;
  189. animation.removedOnCompletion = NO;
  190. animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
  191. animation.repeatCount = MAXFLOAT;
  192. animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(self.idCardLocation.frame.origin.x,self.idCardLocation.frame.origin.y + self.idCardLocation.frame.size.height / 2)];
  193. animation.toValue = [NSValue valueWithCGPoint:CGPointMake(self.idCardLocation.frame.origin.x + self.idCardLocation.frame.size.width, self.idCardLocation.frame.origin.y + self.idCardLocation.frame.size.height / 2)];
  194. return animation;
  195. }
  196. - (void) stopAnimation {
  197. [self.mScanLineImg removeFromSuperview];
  198. }
  199. - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
  200. return UIInterfaceOrientationMaskPortrait;
  201. }
  202. #endif
  203. @end