AVCapture iOS 系统相机知多少 - AVFoundation

2,676 阅读11分钟

几个枚举值

捕捉画面的质量的属性

我们可以通过设置AVCaptureSession的一些属性来改变捕捉画面的质量  
但是要注意:size相关的属性的时候需要首先进行测试设备是否支持
判断方法是  canSetSessionPreset 

AVCaptureSessionPresetPhoto ——适用于高分辨率照片质量输出

AVCaptureSessionPresetHigh ——适用于高质量视频和音频输出

AVCaptureSessionPresetMedium ——适用于中等质量输出,适合通过WiFi共享的输出视频和音频比特率

AVCaptureSessionPresetLow  ——适用于低质量输出,实现适合通过3G共享的输出视频和音频比特率

AVCaptureSessionPreset320x240 ——适用于320x240视频输出

AVCaptureSessionPreset352x288 ——适用于352x288视频输出

AVCaptureSessionPreset640x480 ——适用于640x480视频输出

AVCaptureSessionPreset960x540 ——适用于960x540视频输出

AVCaptureSessionPreset1280x720 ——适用于1280x720视频输出

AVCaptureSessionPreset1920x1080 ——适用于1920x1080视频输出

AVCaptureSessionPreset3840x2160 ——适用于3840x2160(UHD 4K)视频输出

AVCaptureSessionPresetiFrame960x540 ——可生成960x540 Apple iFrame视频和音频内容。以使用AAC音频以~30 Mbits / sec的速度实现960x540质量的iFrame H.264视频。 以iFrame格式捕获的QuickTime影片最适合编辑应用程序

AVCaptureSessionPresetiFrame1280x720 ——可生成1280x720 Apple iFrame视频和音频内容。以使用AAC音频以~40 Mbits / sec的速度实现1280x720质量的iFrame H.264视频。 以iFrame格式捕获的QuickTime影片最适合编辑应用程序

AVCaptureSessionPresetInputPriority ——指示会话输入的格式优先,此更改表明客户端选择的输入格式现在决定了输出端提供的服务质量等级。当客户端将会话预设设置为除AVCaptureSessionPresetInputPriority以外的任何其他内容时,会话将继续负责配置输入和输出,并可根据需要随意更改其输入的activeFormat

设置摄像头的方向

typedef NS_ENUM(NSInteger, AVCaptureDevicePosition) {
 AVCaptureDevicePositionUnspecified         = 0,    // 最近打开的方向,记录最近时间打开的方向
 AVCaptureDevicePositionBack                = 1,    // 后置摄像头
 AVCaptureDevicePositionFront               = 2     // 前置摄像头
} NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;   

设置闪光灯模式

typedef NS_ENUM(NSInteger, AVCaptureFlashMode) {
 AVCaptureFlashModeOff  = 0,    // 关闭闪光灯
 AVCaptureFlashModeOn   = 1,   // 打开闪光灯
 AVCaptureFlashModeAuto = 2   // 自动模式
} NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;

手电筒模式

typedef NS_ENUM(NSInteger, AVCaptureTorchMode) {
 AVCaptureTorchModeOff  = 0,    // 手电筒关闭
 AVCaptureTorchModeOn   = 1,    // 手电筒打开
 AVCaptureTorchModeAuto = 2,   // 手电筒自动模式
} NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;

系统对焦模式

typedef NS_ENUM(NSInteger, AVCaptureAutoFocusSystem) {
AVCaptureAutoFocusSystemNone              = 0,      // 不设置对焦模式
AVCaptureAutoFocusSystemContrastDetection = 1,    //  对比度检测对焦
AVCaptureAutoFocusSystemPhaseDetection    = 2,       // 相位检测对焦
} NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

视频防抖动模式

typedef NS_ENUM(NSInteger, AVCaptureVideoStabilizationMode) {
    AVCaptureVideoStabilizationModeOff       = 0,     // 视频防抖动模式关闭
    AVCaptureVideoStabilizationModeStandard  = 1,  // 视频防抖标准模式
    AVCaptureVideoStabilizationModeCinematic = 2,  // 视频防抖电影模式
    AVCaptureVideoStabilizationModeAuto      = -1,   // 视频防抖自动模式
} NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

焦距调整

typedef NS_ENUM(NSInteger, AVCaptureFocusMode) {
 AVCaptureFocusModeLocked              = 0,     //  锁定对焦
 AVCaptureFocusModeAutoFocus           = 1,   //  自动对焦模式
 AVCaptureFocusModeContinuousAutoFocus = 2,  // 连续自动对焦
} NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;

自动对焦范围限制

typedef NS_ENUM(NSInteger, AVCaptureAutoFocusRangeRestriction) {
 AVCaptureAutoFocusRangeRestrictionNone = 0,    // 不限制
 AVCaptureAutoFocusRangeRestrictionNear = 1,     //  近距离对焦模式
 AVCaptureAutoFocusRangeRestrictionFar  = 2,      //   远距离对焦模式
} NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;

曝光模式设置

typedef NS_ENUM(NSInteger, AVCaptureExposureMode) {
 AVCaptureExposureModeLocked                            = 0,    // 锁定曝光
 AVCaptureExposureModeAutoExpose                        = 1,  // 自动曝光模式
 AVCaptureExposureModeContinuousAutoExposure            = 2,  //   连续自动曝光模式
 AVCaptureExposureModeCustom NS_ENUM_AVAILABLE_IOS(8_0) = 3,   // 自定义曝光模式
} NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;

白平衡模式

typedef NS_ENUM(NSInteger, AVCaptureWhiteBalanceMode) {
 AVCaptureWhiteBalanceModeLocked            = 0,     // 锁定白平衡模式
 AVCaptureWhiteBalanceModeAutoWhiteBalance         = 1,  //   自动
    AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance = 2,  // 连续自动
} NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;

授权状态 用户是否已经允许启用设备

typedef NS_ENUM(NSInteger, AVAuthorizationStatus) {
 AVAuthorizationStatusNotDetermined = 0,    //  授权状态未确定
 AVAuthorizationStatusRestricted,     //  授权受限
 AVAuthorizationStatusDenied,         //   授权被拒绝
 AVAuthorizationStatusAuthorized    //   授权被许可
} NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;

表示传输控件当前播放模式的枚举 - 播放控制模式

typedef NS_ENUM(NSInteger, AVCaptureDeviceTransportControlsPlaybackMode) {
 AVCaptureDeviceTransportControlsNotPlayingMode      = 0,
 AVCaptureDeviceTransportControlsPlayingMode         = 1
} NS_AVAILABLE(10_7, NA) __TVOS_PROHIBITED;

几个对象

存在的几个对象的理解

  • AVCaptureDevice //硬件设备
  • AVCaptureInput //输入的设备
  • AVCaptureOutput //输出的数据
  • AVCaotureSession //协助input和output的数据传输

关系:
有很多Device的input和很多类型的Output,都通过一个CaptureSession来控制进行传输,即:CaputureDevice适配AVCaptureInput,通过Session来输入到AVCaptureOutput中,这样就达到了从设备到文件等持久传输的目的(如从相机设备采集图像到UIImage中)

那么如果视频输入(input)和对应的视频输出(output),音频对应音频,因而需要建立对应的Connections(连接),来各自连接它们,这个连接对象是由AVCaptureSession持有的,这个对象为 AVCaptureConnection,可以控制input和output的数据传输(通过各种的input port,都可以获取到相应的数据)

AVCaotureSession

self.captureSession = [[AVCaptureSession alloc] init];
[self.captureSession startRunning];

需要创建一个session,发running消息,响应,就把输入设备的东西,提交到输出设备中。

如果想在一个已经使用session中(已经startRunning)更换新的device,删除旧的,方法

[session beginConfiguration];
[session commitConfiguration];
//切换摄像头
- (BOOL)switchCameras {

    //判断是否有多个摄像头
    if (![self canSwitchCameras]){
        return NO;
    }
    
    //获取当前设备的反向设备
    NSError *error;
    AVCaptureDevice *videoDevice = [self inactiveCamera];//返回当前未激活的摄像头
    
    
    //将输入设备封装成AVCaptureDeviceInput
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
    
    //判断videoInput 是否为nil
    if (videoInput)
    {
        //标注原配置变化开始
        [self.captureSession beginConfiguration];
        
        //将捕捉会话中,原本的捕捉输入设备移除
        [self.captureSession removeInput:self.activeVideoInput];
        
        //判断新的设备是否能加入
        if ([self.captureSession canAddInput:videoInput])
        {
            //能加入成功,则将videoInput 作为新的视频捕捉设备
            [self.captureSession addInput:videoInput];
            
            //将获得设备 改为 videoInput
            self.activeVideoInput = videoInput;
        }else
        {
            //如果新设备,无法加入。则将原本的视频捕捉设备重新加入到捕捉会话中
            [self.captureSession addInput:self.activeVideoInput];
        }
        
        //配置完成后, AVCaptureSession commitConfiguration 会分批的将所有变更整合在一起。
        [self.captureSession commitConfiguration];
    }else{
        return NO;
    }
    return YES;
}

AVCaptureDevice

Device是对硬件的一对一的表示,一个AVCaptureDevice对象,对应一个实际的硬件设备\

/* 创建并配置输入设备 */
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    if (device==nil) {
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" 
                   message:@"设备没有摄像头" 
                   preferredStyle:UIAlertControllerStyleAlert];
        [alert addAction:[UIAlertAction actionWithTitle:@"确认" 
        style:UIAlertActionStyleDefault 
        handler:^(UIAlertAction * _Nonnull action) {

        }]];
        [self presentViewController:alert animated:YES completion:nil];
        return;
    }
    // Device
    _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    // Input
    _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
    
    //Out put
    AVCaptureStillImageOutput *imageOutput; //图片的输出
    AVCaptureMovieFileOutput *movieOutput; //视频的输出
    
    self.movieOutput = [[AVCaptureMovieFileOutput alloc]init];
    
    

然后添加input到session的模式(检查是否可添加)

// Session 添加输入输出设备前要判断该手机(设备)能否添加输入输出设备。
    _session = [[AVCaptureSession alloc]init];
    [_session setSessionPreset:AVCaptureSessionPresetHigh];
    if ([_session canAddInput:self.input])
    {
        [_session addInput:self.input];
    }

    //if ([_session canAddOutput:self.output])
    //{
    //    [_session addOutput:self.output];
    //}
    if ([self.captureSession canAddOutput:self.movieOutput]){
        [self.captureSession addOutput:self.movieOutput];
    }

AVCaptureOutput

Output的使用
ios中,分为MovieFile(输出成movie文件)、VideoData(适用各个Frame的处理)、AudioData(声音采集)、StillImage(静态图像拍照)几种output,它们都继承与AVCaptureOutput

AVCaptureDeviceInput

    self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];

相机的几个参数

感光度 ISO

在数码相机中 ISO 表示感光元件的感光的速度。
感光度 ISO 数值越高就说明该感光元器件的感光能力越强,对曝光量的要求就越少。一般情况下,ISO 值越低,相片的质量越高,相片的细节表现的得越细腻;ISO 值越高,相片的亮度就越高,而相片的质量会随着 ISO值的升高而降低,噪点会变得越来越严重,但高 ISO 值可以弥补光线的不足。

获取AVCaptureDevice的感光度ISO

@property(nonatomic, readonly) float ISO;

当前曝光的感光度 ISO 值。此属性通过应用于信号的增益值返回传感器对光的灵敏度。

仅支持minISOmaxISO之间的ISO值;值越高,图像越嘈杂。
无论曝光模式如何,都可以随时读取属性值,但只能使用-setExposureModeCustomWithDuration:ISO:completionHandler:方法进行设置。

常量const float AVCaptureISOCurrent;表示调用者不希望为 ISO 属性指定值,而是应将其设置为其当前值。

光圈

光圈是一个用来控制光线透过镜头,进入机身内感光面的光量的装置;它通常是在镜头内。
表达光圈大小我们是用F值:光圈F值 = 镜头的焦距/镜头口径的直径;从以上的公式可知要达到相同的光圈F值,长焦距镜头的口径要比短焦距镜头的口径大。
当光圈物理孔径不变时,镜头中心与感光器件距离愈远,F数愈大,
反之,镜头中心与感光器件距离愈近,通过光孔到达感光器件的光密度愈高,F数就愈小。
完整的光圈值系列如下: (”全开”)F1, F1.4, F2, F2.8, F4, F5.6, F8, F11, F16, F22, F32, F44, F64(“小孔”)
光圈F值愈小,在同一单位时间内的进光量便愈多,而且上一级的进光量刚是下一级的一倍,例如光圈从F8调整到F5.6,进光量便多一倍,我们也说光圈开大了一级。

快门

快门是照相机用来控制感光片有效曝光时间的装置。
是照相机的一个重要组成部分,它的结构、形式及功能是衡量照相机档次的一个重要因素。一般而言快门的时间范围越大越好。秒数低适合拍运动中的物体,某款相机就强调快门最快能到1/16000秒,可轻松抓住急速移动的目标。不过当你要拍的是夜晚的车水马龙,快门时间就要拉长,常见照片中丝绢般的水流效果也要用慢速快门才能拍出来

快门速度单位是“秒”。专业135相机的最高快门速度达到1/16000秒。常见的快门速度有:1 1/2 1/4 1/8 1/15 1/30 1/60 1/125 1/250 1/500 1/1000 1/2000等。相邻两级的快门速度的曝光量相差一倍,我们常说相差一级。如1/60秒比1/125秒的曝光量多一倍,即1/60秒比1/125秒速度慢一级或称低一级。

曝光

曝光就是 光圈、快门 和 感光度ISO 的组合。
[曝光值] 是由快门速度值和光圈值组合表示摄影镜头通光能力的一个数值。

曝光:是指当你按相机快门按钮的时候,快门(镜头外的世界和机身内部感光元件之间的门)会打开,过一段时间再关上;就在这一小段时间之内,光线会从镜头钻进来,照在长方形的感光元件上边,感光元件上几千万的感光点就会记录照到它上边的光的色彩;于是,就得到一张照片了。

可以这样认为:光圈值大小其实就是那个小圆窗户开多大;快门(速度)就是窗户打开多久。\

假若一个镜头光圈全开为 F4,用摄影行话来说,光圈 F4 快门速度 1 秒为正确曝光值,那 F5.6 和 2 秒以及 F8 和 4 秒也同样能得到准确曝光的图片。

一张正确曝光的图片可以有N种不同的光圈和快门速度组合。

曝光的一些属性

属性类型描述
exposureDurationCMTime一个只读属性,表示曝光时间;仅支持minExposureDurationmaxExposureDuration之间的曝光持续时间值。无论曝光模式如何,都可以随时读取曝光时间。
exposureTargetOffsetfloat一个只读属性,表示当前场景的计量曝光水平与目标曝光值之间的差异;以EV为单位。
exposureTargetBiasfloat一个只读属性,以EV单位应用于目标暴露值的偏差。当曝光模式为AVCaptureExposureModeAutoExposeAVCaptureExposureModeLocked时,偏差将影响测光(exposureTargetOffset)和实际曝光等级:曝光时间exposureDuration和感光度ISO。 当曝光模式为AVCaptureExposureModeCustom时,它只会影响测光。
minExposureTargetBiasfloat一个只读属性,EV单位支持的最小曝光偏差。
maxExposureTargetBiasfloat一个只读属性,以EV为单位的最大支持曝光偏差。
activeMaxExposureDurationCMTime自动曝光算法中定义的最长曝光持续时间(以秒为单位)。
adjustingExposureBOOL一个只读属性,指示设备当前是否正在调整其曝光设置。
exposureModeAVCaptureExposureMode设备的曝光模式。在更改此属性的值之前,必须调用-lockForConfiguration:以锁定AVCaptureDevice;否则,设置此属性的值会引发异常。完成配置设备后,请调用-unlockForConfiguration以释放锁定并允许其他设备配置设置。
exposurePointOfInterestSupportedBOOL一个只读属性,指示设备是否支持曝光的兴趣点。
exposurePointOfInterestCGPoint曝光的兴趣点。