前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS 自定义相机:基础知识储备

iOS 自定义相机:基础知识储备

作者头像
公众号iOS逆向
发布2021-07-05 21:10:04
2.1K0
发布2021-07-05 21:10:04
举报
文章被收录于专栏:iOS逆向与安全iOS逆向与安全
  • 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];

点击屏幕对焦

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS逆向 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • I、常用基础功能
    • 1.1模拟拍照动作
      • 1.2 能否切换前置后置
        • 1.3 从输出的元数据中捕捉人脸
          • 1.4 捕获每一帧图像: AVCaptureVideoDataOutputSampleBufferDelegate
            • 1.5 点击屏幕对焦:聚焦
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档