一 、AVCaptureSession 基础配置:
// 1. 创建捕捉会话。AVCaptureSession
self.captureSession = [[AVCaptureSession alloc]init];
// 2. 设置分辨率
/*
AVCaptureSessionPresetHigh
AVCaptureSessionPresetMedium
AVCaptureSessionPresetLow
AVCaptureSessionPreset640x480
AVCaptureSessionPreset1280x720
AVCaptureSessionPresetPhoto
*/
AVCaptureSessionPreset SessionPreset = AVCaptureSessionPresetPhoto;
if ([self.captureSession canSetSessionPreset:SessionPreset]) {
self.captureSession.sessionPreset = SessionPreset;
}
// 3. 输入源
int frameRate;
CMTime frameDuration = kCMTimeInvalid;
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
if ([captureDevice lockForConfiguration:&error]) {
frameRate = 30;
frameDuration = CMTimeMake( 1, frameRate );
captureDevice.activeVideoMaxFrameDuration = frameDuration;
captureDevice.activeVideoMinFrameDuration = frameDuration;
[captureDevice unlockForConfiguration];
}
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
// 4. 输出源
AVCaptureStillImageOutput *imageOutput = [[AVCaptureStillImageOutput alloc]init];
imageOutput.outputSettings = @{AVVideoCodecKey:AVVideoCodecJPEG};
// 5. 开始添加输入输出
[self.captureSession beginConfiguration];
if (deviceInput && [self.captureSession canAddInput:deviceInput]) {
[self.captureSession addInput:deviceInput];
self.activeVideoInput = deviceInput;
}
if ([self.captureSession canAddOutput:self.imageOutput]) {
[self.captureSession addOutput:self.imageOutput];
}
[self.captureSession commitConfiguration];
二 、AVCaptureSession 启动与停止:
// 启动session
- (void)startSession {
if (![self.captureSession isRunning])
{
dispatch_async(self.videoQueue, ^{
[self.captureSession startRunning];
});
}
}
// 停止session
- (void)stopSession {
if ([self.captureSession isRunning])
{
dispatch_async(self.videoQueue, ^{
[self.captureSession stopRunning];
});
}
}
三 、AVCaptureDevice(捕捉设备)相关操作:对焦 白平衡 曝光 HDR 镜头位置 感光度 等
// 当前活跃设备
- (AVCaptureDevice *)activeCamera {
return self.activeVideoInput.device;
}
// 聚焦
- (void)focusAtPoint:(CGPoint)point {
AVCaptureDevice *device = [self activeCamera];
if ([device isFocusPointOfInterestSupported] && [device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
NSError *error;
if ([device lockForConfiguration:&error]) {
device.focusPointOfInterest = point;
device.focusMode = AVCaptureFocusModeContinuousAutoFocus;
[device unlockForConfiguration];
}
}
}
// 对兴趣点进行曝光
- (void)exposeAtPoint:(CGPoint)point {
AVCaptureDevice *device = [self activeCamera];
AVCaptureExposureMode exposureMode =AVCaptureExposureModeContinuousAutoExposure;
if ([device isFocusPointOfInterestSupported] && [device isExposureModeSupported:exposureMode]) {
NSError *error;
if ([device lockForConfiguration:&error]) {
device.exposurePointOfInterest = point;
device.exposureMode = exposureMode;
[device unlockForConfiguration];
}
}
}
// 手动曝光调节
- (void)setExposureWithNewValue:(CGFloat)newExposureValue{
NSError *error;
AVCaptureDevice *device = [self activeCamera];
if ([device lockForConfiguration:&error]) {
[device setExposureTargetBias:newExposureValue completionHandler:nil];
[device unlockForConfiguration];
}
}
// 设置平滑对焦
- (void)setSmoothFocus:(BOOL)smoothFocusEnabled{
NSError *error;
AVCaptureDevice *captureDevice = [self activeCamera];
if ([captureDevice lockForConfiguration:&error]) {
[captureDevice setSmoothAutoFocusEnabled:smoothFocusEnabled];
[captureDevice unlockForConfiguration];
}
}
// 白平衡
- (void)setWhiteBalanceMode:(AVCaptureWhiteBalanceMode)whiteBalanceMode{
AVCaptureDevice *device = [self activeCamera];
if ([device isWhiteBalanceModeSupported:whiteBalanceMode]) {
NSError *error;
if ([device lockForConfiguration:&error]) {
device.whiteBalanceMode = whiteBalanceMode;
[device unlockForConfiguration];
}
}
}
/**
自定义白平衡模式
temperature: 通过华氏温度调节 (-150-~250)
tint: 通过色调调节 (-150-~150)
*/
-(AVCaptureWhiteBalanceGains)clampGains:(AVCaptureWhiteBalanceGains)gains toMinVal:(CGFloat)minVal andMaxVal:(CGFloat)maxVal {
AVCaptureWhiteBalanceGains tmpGains = gains;
tmpGains.blueGain = MAX(MIN(tmpGains.blueGain , maxVal), minVal);
tmpGains.redGain = MAX(MIN(tmpGains.redGain , maxVal), minVal);
tmpGains.greenGain = MAX(MIN(tmpGains.greenGain, maxVal), minVal);
return tmpGains;
}
-(void)setWhiteBlanceValueByTemperature:(CGFloat)temperature device:(AVCaptureDevice *)device {
if ([device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeLocked]) {
[device lockForConfiguration:nil];
// 白平衡增益
AVCaptureWhiteBalanceGains currentGains = device.deviceWhiteBalanceGains;
CGFloat currentTint = [device temperatureAndTintValuesForDeviceWhiteBalanceGains:currentGains].tint;
AVCaptureWhiteBalanceTemperatureAndTintValues tempAndTintValues = {
.temperature = temperature,
.tint = currentTint,
};
AVCaptureWhiteBalanceGains deviceGains = [device deviceWhiteBalanceGainsForTemperatureAndTintValues:tempAndTintValues];
CGFloat maxWhiteBalanceGain = device.maxWhiteBalanceGain;
deviceGains = [self clampGains:deviceGains toMinVal:1 andMaxVal:maxWhiteBalanceGain];
[device setWhiteBalanceModeLockedWithDeviceWhiteBalanceGains:deviceGains completionHandler:nil];
[device unlockForConfiguration];
}
}
-(void)setWhiteBlanceValueByTint:(CGFloat)tint device:(AVCaptureDevice *)device {
if ([device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeLocked]) {
[device lockForConfiguration:nil];
CGFloat maxWhiteBalaceGain = device.maxWhiteBalanceGain;
AVCaptureWhiteBalanceGains currentGains = device.deviceWhiteBalanceGains;
currentGains = [self clampGains:currentGains toMinVal:1 andMaxVal:maxWhiteBalaceGain];
CGFloat currentTemperature = [device temperatureAndTintValuesForDeviceWhiteBalanceGains:currentGains].temperature;
AVCaptureWhiteBalanceTemperatureAndTintValues tempAndTintValues = {
.temperature = currentTemperature,
.tint = tint,
};
AVCaptureWhiteBalanceGains deviceGains = [device deviceWhiteBalanceGainsForTemperatureAndTintValues:tempAndTintValues];
deviceGains = [self clampGains:deviceGains toMinVal:1 andMaxVal:maxWhiteBalaceGain];
[device setWhiteBalanceModeLockedWithDeviceWhiteBalanceGains:deviceGains completionHandler:nil];
[device unlockForConfiguration];
}
}
// 调节镜头的位置
- (void)setLensPosition:(float)lensPosition{
AVCaptureDevice *captureDevice = [self activeCamera];
NSError *error;
if ([captureDevice lockForConfiguration:&error]) {
[captureDevice setFocusModeLockedWithLensPosition:lensPosition completionHandler:^(CMTime syncTime) {
}];
[captureDevice unlockForConfiguration];
}
}
/*
调解自定义曝光时长 感光度
*/
- (void)setExposureModeWithDuration:(CMTime)duration ISO:(float)ISO completionHandler:(void(^)(CMTime syncTime))handler{
AVCaptureDevice *captureDevice = [self activeCamera];
NSError *error;
if ([captureDevice lockForConfiguration:&error]) {
[captureDevice setExposureModeCustomWithDuration:duration ISO:ISO completionHandler:^(CMTime syncTime) {
}];
[captureDevice unlockForConfiguration];
}
}
四 、硬件相关操作:
// 获取指定位置摄像头 (前置摄像头 & 后置摄像头)
- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition)position {
NSArray *deviceArray = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in deviceArray)
{
if (device.position == position) {
return device;
}
}
return nil;
}
//设置手电筒模式
- (void)setTorchMode:(AVCaptureTorchMode)torchMode {
/*
AVCaptureTorchModeOff = 0,
AVCaptureTorchModeOn = 1,
AVCaptureTorchModeAuto = 2,
*/
AVCaptureDevice *device = [self activeCamera];
if ([device isTorchModeSupported:torchMode]) {
NSError *error;
if ([device lockForConfiguration:&error]) {
device.torchMode = torchMode;
[device unlockForConfiguration];
}
}
}
//设置闪光灯
- (void)setFlashMode:(AVCaptureFlashMode)flashMode {
//获取当前设备
AVCaptureDevice *device = [self activeCamera];
//判断是否支持闪光灯模式
if ([device isFlashModeSupported:flashMode]) {
//如果支持,则锁定设备
NSError *error;
if ([device lockForConfiguration:&error]) {
/*
AVCaptureFlashModeOff = 0,
AVCaptureFlashModeOn = 1,
AVCaptureFlashModeAuto = 2,
*/
device.flashMode = flashMode;
[device unlockForConfiguration];
}
}
}
// 切换摄像头,返回操作结果
- (BOOL)switchCameras{
if (![self canSwitchCameras]) {
return NO;
}
// 获取反向摄像头
AVCaptureDevice *videoDevice = [self inactiveCamera];
NSError *error;
AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
if (videoInput)
{
[self.captureSession beginConfiguration];
[self.captureSession removeInput:self.activeVideoInput];
if ([self.captureSession canAddInput:videoInput])
{
[self.captureSession addInput:videoInput];
self.activeVideoInput = videoInput;
}else{
[self.captureSession addInput:self.activeVideoInput];
}
[self.captureSession commitConfiguration];
}else
{
return NO;
}
return YES;
}
//判断是否允许切换摄像头
- (BOOL)canSwitchCameras {
return self.cameraCount > 1;
}
//获取反向摄像头
- (AVCaptureDevice *)inactiveCamera {
//通过查找当前激活摄像头的反向摄像头获得,如果设备只有1个摄像头,则返回nil
AVCaptureDevice *device = nil;
if (self.cameraCount > 1)
{
if ([self activeCamera].position == AVCaptureDevicePositionBack) {
device = [self cameraWithPosition:AVCaptureDevicePositionFront];
}else
{
device = [self cameraWithPosition:AVCaptureDevicePositionBack];
}
}
return device;
}
网友评论