AVFoundation-缩放

iOS7以前使用AVCaptureConnection

通过 AVCaptureConnection 的属性对摄像头缩放进行有限制的支持,开发者可以通过调整连接缩放的值从默认的1.0增加到 videoMaxScaleAndCropFactor属性定义的最大值

需要用到AVCaptureConnection的两个属性

  • @property(nonatomic) CGFloat videoScaleAndCropFactor
  • @property(nonatomic, readonly) CGFloat videoMaxScaleAndCropFactor

videoScaleAndCropFactor这个属性取值范围是1.0-videoMaxScaleAndCropFactor

示例:

1
2
3
4
5
6
7
8
9
10
11

AVCaptureStillImageOutput* output = (AVCaptureStillImageOutput*)[self.captureSession.outputs objectAtIndex:0];
AVCaptureConnection *videoConnection = [output connectionWithMediaType:AVMediaTypeVideo];
CGFloat maxScale = videoConnection.videoMaxScaleAndCropFactor;
CGFloat zoom = maxScale / 50;
if (zoom < 1.0f || zoom > maxScale)
{
return;
}
videoConnection.videoScaleAndCropFactor += zoom;
self.preVideoView.transform = CGAffineTransformScale(self.preVideoView.transform, zoom, zoom);

iOS7以后 使用 AVCaptureDevice

AVCaptureDevice 提供了属性 videoZoomFactor用于控制捕捉设备的缩放等级,这个值最小为1.0,最大值由捕捉设备的 activeFormat 值确定

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//videoMaxZoomFactor值大于1.0,则捕捉设备支持缩放功能
- (BOOL)cameraSupportsZoom {
return self.activeCamera.activeFormat.videoMaxZoomFactor > 1.0f; // 1
}
//确定最大缩放因子,4.0f是随意设置的
- (CGFloat)maxZoomFactor {
return MIN(self.activeCamera.activeFormat.videoMaxZoomFactor, 4.0f); // 2
}

- (void)setZoomValue:(CGFloat)zoomValue { // 3
if (!self.activeCamera.isRampingVideoZoom) {

NSError *error;
if ([self.activeCamera lockForConfiguration:&error]) { // 4

// Provide linear feel to zoom slider
CGFloat zoomFactor = pow([self maxZoomFactor], zoomValue); // 5
//应用程序提供的缩放范围1X到4X 是指数形式的,所以要提供范围线性增长的感觉
self.activeCamera.videoZoomFactor = zoomFactor;

[self.activeCamera unlockForConfiguration]; // 6

} else {
[self.delegate deviceConfigurationFailedWithError:error];
}
}
}

添加监听缩放

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
- (BOOL)setupSessionInputs:(NSError **)error {
BOOL success = [super setupSessionInputs:error]; // 1
if (success) {
[self.activeCamera addObserver:self // 2
forKeyPath:@"videoZoomFactor"
options:0
context:&THRampingVideoZoomFactorContext];
[self.activeCamera addObserver:self // 3
forKeyPath:@"rampingVideoZoom"
options:0
context:&THRampingVideoZoomContext];

}
return success;
}

- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {

if (context == &THRampingVideoZoomContext) {
[self updateZoomingDelegate]; // 4
} else if (context == &THRampingVideoZoomFactorContext) {
if (self.activeCamera.isRampingVideoZoom) {
[self updateZoomingDelegate]; // 5
}
} else {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
}