我有一个简单的AVCaptureSession运行在我的应用程序中获取相机馈送并拍照。我如何使用UIGestureRecognizer
来实现相机的“缩放变焦”功能?AVCaptureDevice相机变焦
回答
接受的答案实际上已过时,我不确定它实际上是否会放大图像的照片。有一种方法可以放大像bcattle答案所述。他的回答问题是,它不承担用户可以放大然后从该缩放位置重新启动的事实。他的解决方案会创造出一些不太优雅的跳跃。
这样做的最简单和最优雅的方式是使用捏手势的速度。
-(void) handlePinchToZoomRecognizer:(UIPinchGestureRecognizer*)pinchRecognizer {
const CGFloat pinchVelocityDividerFactor = 5.0f;
if (pinchRecognizer.state == UIGestureRecognizerStateChanged) {
NSError *error = nil;
if ([videoDevice lockForConfiguration:&error]) {
CGFloat desiredZoomFactor = device.videoZoomFactor + atan2f(pinchRecognizer.velocity, pinchVelocityDividerFactor);
// Check if desiredZoomFactor fits required range from 1.0 to activeFormat.videoMaxZoomFactor
device.videoZoomFactor = MAX(1.0, MIN(desiredZoomFactor, device.activeFormat.videoMaxZoomFactor));
[videoDevice unlockForConfiguration];
} else {
NSLog(@"error: %@", error);
}
}
}
我发现将arctan函数添加到速度会缓解放大缩小效果。它不完美,但效果足以满足需求。也许有可能是另一种功能,缓解变焦出来的时候,几乎达到1
注意:另外,捏合手势的规模从0到无穷以0比1的存在捏在(缩小)和1到无限张开(放大)。为了获得放大缩小效果,你需要有一个数学公式。速度实际上是从无限到无限,以0为起点。
编辑:修复了范围异常的崩溃。感谢@garafajon!
谢谢。使用它不会得到范围异常:\t \t \t CGFloat desiredZoom = videoDevice.videoZoomFactor + atan(pinchRecognizer.velocity/pinchZoomScaleFactor); \t \t \t videoDevice.videoZoomFactor = MAX(1.0,MIN(desiredZoom,videoDevice.activeFormat.videoMaxZoomFactor)); – garafajon 2015-10-01 18:32:08
太棒了!有用。 – Sourabh 2015-12-08 12:34:07
请注意,速度可以返回nan。你可能想在继续计算之前检查一下:if(isnan(pinchRecognizer.velocity)){return; } – Masa 2016-03-15 08:54:33
许多人都试图通过将图层上的transform属性设置为CGAffineTransformMakeScale(gesture.scale.x, gesture.scale.y);
请参阅here,以获得完整的缩放缩放实现。
感谢您的回复。但是,仅仅改变视频预览视图的缩放比例实际上会改变摄像机硬件的缩放比例? – 2012-04-19 03:12:21
它没有。这就是为什么即使苹果的相机不真正'放大'。这只是一些CGAffines,还有一些奇特的种植。 – CodaFi 2012-04-19 03:17:11
对,相机只是使用“数码变焦”。但是除缩放视频预览视图之外,我还必须做些什么才能真正将图像写入磁盘“缩放”? – 2012-04-19 03:42:12
从iOS 7开始,您可以使用AVCaptureDevice
的videoZoomFactor
属性直接设置缩放。
将UIPinchGestureRecognizer
的scale
属性与缩放常数结合为videoZoomFactor
。这将让你改变灵敏度的味道:
-(void) handlePinchToZoomRecognizer:(UIPinchGestureRecognizer*)pinchRecognizer {
const CGFloat pinchZoomScaleFactor = 2.0;
if (pinchRecognizer.state == UIGestureRecognizerStateChanged) {
NSError *error = nil;
if ([videoDevice lockForConfiguration:&error]) {
videoDevice.videoZoomFactor = 1.0 + pinchRecognizer.scale * pinchZoomScaleFactor;
[videoDevice unlockForConfiguration];
} else {
NSLog(@"error: %@", error);
}
}
}
注意AVCaptureDevice
,沿一切有关AVCaptureSession
,不是线程安全的。所以你可能不想从主队列中做到这一点。
我使用的是iOS SDK 8.3和AVfoundation框架和我使用下面的方法处理为:
nameOfAVCaptureVideoPreviewLayer.affineTransform = CGAffineTransformMakeScale(scaleX, scaleY)
对于保存照片与我用下面的方法相同规模:
nameOfAVCaptureConnection.videoScaleAndCropFactor = factorNumber;
代码波纹管是在尺度
[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if(imageDataSampleBuffer != NULL){
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [UIImage imageWithData:imageData];
}
}];
在SWIF获取图像t版本,只需在videoZoomFactor上传递缩放数字即可放大/缩小。以下UIPinchGestureRecognizer处理程序中的代码将解决此问题。
do {
try device.lockForConfiguration()
switch gesture.state {
case .began:
self.pivotPinchScale = device.videoZoomFactor
case .changed:
var factor = self.pivotPinchScale * gesture.scale
factor = max(1, min(factor, device.activeFormat.videoMaxZoomFactor))
device.videoZoomFactor = factor
default:
break
}
device.unlockForConfiguration()
} catch {
// handle exception
}
在这里,pivotPinchScale是一个CGFloat属性,它在控制器的某个地方声明。
您也可以参考以下项目了解相机如何与UIPinchGestureRecognizer配合使用。 https://github.com/DragonCherry/CameraPreviewController
夫特4
添加捏手势识别到最前视图,并将其连接到这个动作(pinchToZoom)。 captureDevice应该是当前为捕获会话提供输入的实例。 pinchToZoom可为前端&后端提供平滑缩放捕捉设备。
@IBAction func pinchToZoom(_ sender: UIPinchGestureRecognizer) {
guard let device = captureDevice else { return }
func minMaxZoom(_ factor: CGFloat) -> CGFloat { return min(max(factor, 1.0), device.activeFormat.videoMaxZoomFactor) }
func update(scale factor: CGFloat) {
do {
try device.lockForConfiguration()
defer { device.unlockForConfiguration() }
device.videoZoomFactor = factor
} catch {
debugPrint(error)
}
}
let newScaleFactor = minMaxZoom(pinch.scale * zoomFactor)
switch sender.state {
case .began: fallthrough
case .changed: update(scale: newScaleFactor)
case .ended:
zoomFactor = minMaxZoom(newScaleFactor)
update(scale: zoomFactor)
default: break
}
}
在摄像头或vc上声明zoomFactor会很有用。我通常把它放在具有AVCaptureSession的同一个单例中。这将作为CaptureDevice的videoZoomFactor的默认值。
var zoomFactor: Float = 1.0
- 1. AVFoundation相机变焦
- 2. 相机变焦效果
- 3. 轨迹球相机变焦
- 4. UIImagePicker禁用相机变焦
- 5. AVCaptureDevice无法捕捉回相机
- 6. 相机焦距
- 7. 的iOS 5 - AVCaptureDevice设置对焦点和对焦模式的冻结直播相机图片
- 8. Embarcadero FireMonkey 3D相机旋转和变焦
- 9. 在iPhone上使用相机变焦
- 10. ThreeJS改变相机的旋转焦点
- 11. Android相机变焦和性能
- 12. Android - 相机变焦不起作用
- 13. 正视相机和变焦控制
- 14. 如何将相机变焦至最大?
- 15. 在相机中添加相机的变焦控制
- 16. 相机对焦IOS
- 17. getUserMedia()相机焦点
- 18. ios相机失焦
- 19. S60相机对焦
- 20. 安卓相机的变焦和平滑变焦有什么区别?
- 21. Android相机触摸焦点
- 22. HTML5 getUserMedia相机聚焦
- 23. Android相机连续对焦
- 24. iOS相机对焦值
- 25. Android相机自动对焦
- 26. 如何对焦照相机?
- 27. 相机焦距测试
- 28. 平滑相机使变焦倍率改变
- 29. 3JS变焦相机没有轨迹球控制或其他相机控制库
- 30. AVCaptureDevice videoZoomFactor
你要添加捏手势? – Dalvik 2017-10-01 18:25:36