我有一個簡單的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