- 1.1模拟拍照动作
- 1.2 能否切换前置后置
- 1.3 从输出的元数据中捕捉人脸
- 1.4 捕获每一帧图像: AVCaptureVideoDataOutputSampleBufferDelegate
- 1.5 点击屏幕对焦:聚焦
- 1.6 身份证和人头像的宽高比
- 1.7 调整屏幕亮度
- 1.8 获取iPhone设备摄像头所感知的环境光强度
- 1.9 手电筒
- 2.1 扫描线
- 2.1.1 采用动画组进行实现
- 2.1.2 定时调用setNeedsDisplay定时redrawn,来实现实现水平扫描线
- 2.2 iOS13适配【present 半屏问题】
引言
在这里插入图片描述
I、常用基础功能
1.1模拟拍照动作
代码语言:javascript复制 //振动,颤动,摆动
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);// // 播放一下“拍照”的声音,模拟拍照 AudioServicesPlaySystemSound(1108);
1.2 能否切换前置后置
代码语言:javascript复制//
- (BOOL)canSwitchCameras {
return [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count] > 1;
}
1.3 从输出的元数据中捕捉人脸
实现输出流的代理AVCaptureMetadataOutputObjectsDelegate
代码语言:javascript复制 _metadataOutput = [[AVCaptureMetadataOutput alloc]init];
[_metadataOutput setMetadataObjectsDelegate:self queue:self.queue];
[self.videoDataOutput setSampleBufferDelegate:nil queue:self.queue];
代码语言:javascript复制// 检测人脸是为了获得“人脸区域”,做“人脸区域”与“身份证人像框”的区域对比,当前者在后者范围内的时候,才能截取到完整的身份证图像
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if (metadataObjects.count) {
AVMetadataMachineReadableCodeObject *metadataObject = metadataObjects.firstObject;
AVMetadataObject *transformedMetadataObject = [self.previewLayer transformedMetadataObjectForMetadataObject:metadataObject];
CGRect faceRegion = transformedMetadataObject.bounds;
if (metadataObject.type == AVMetadataObjectTypeFace) {
NSLog(@"是否包含头像:%d, facePathRect: %@, faceRegion: %@",CGRectContainsRect(self.faceDetectionFrame, faceRegion),NSStringFromCGRect(self.faceDetectionFrame),NSStringFromCGRect(faceRegion));
if (CGRectContainsRect(self.faceDetectionFrame, faceRegion)) {// 只有当人脸区域的确在小框内时,才再去做捕获此时的这一帧图像
// 为videoDataOutput设置代理,程序就会自动调用下面的代理方法,捕获每一帧图像
if (!self.videoDataOutput.sampleBufferDelegate) {
[self.videoDataOutput setSampleBufferDelegate:self queue:self.queue];
}
}
}
}
}
1.4 捕获每一帧图像: AVCaptureVideoDataOutputSampleBufferDelegate
设置代理
代码语言:javascript复制 _videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
[self.videoDataOutput setSampleBufferDelegate:self queue:self.queue];
从输出的数据流捕捉单一的图像帧
代码语言:javascript复制
#pragma mark - AVCaptureVideoDataOutputSampleBufferDelegate
#pragma mark 从输出的数据流捕捉单一的图像帧
// AVCaptureVideoDataOutput获取实时图像,这个代理方法的回调频率很快,几乎与手机屏幕的刷新频率一样快
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
if ([self.outPutSetting isEqualToNumber:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange]] || [self.outPutSetting isEqualToNumber:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange]]) {
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
if ([captureOutput isEqual:self.videoDataOutput]) {
// 身份证信息识别 (void)iDCardRecognit:(CVImageBufferRef)imageBuffer WithstopRunningBlcok:(void(^)(id make)) stopRunningBlcok finishBlock:(k_finishBlock)finishBlock;
__weak __typeof__(self) weakSelf = self;
[KNScanCardManage iDCardRecognit:imageBuffer WithstopRunningBlcok:^(id _Nonnull sender) {
if ([weakSelf.session isRunning]) {
[weakSelf.session stopRunning];
}
} finishBlock:weakSelf.finishBlock];//imageBuffer
// 身份证信息识别完毕后,就将videoDataOutput的代理去掉,防止频繁调用AVCaptureVideoDataOutputSampleBufferDelegate方法而引起的“混乱”
if (self.videoDataOutput.sampleBufferDelegate) {
[self.videoDataOutput setSampleBufferDelegate:nil queue:self.queue];
}
}
} else {
NSLog(@"输出格式不支持");
}
}
1.5 点击屏幕对焦:聚焦
监听点击事件
代码语言:javascript复制 UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(focusGesture:)];
[self.view addGestureRecognizer:tapGesture];
点击屏幕对焦