ピンチしてズームカメラを作ろうとしていますが、2つの問題が発生しています。 1つ目は、ユーザーがズームインとズームアウトをやりすぎてしまうことです。2つ目は、写真を撮ったときに、ズームインしたビューでは撮影されないことです。これがピンチ機能の私のコードです...
func pinch(pinch: UIPinchGestureRecognizer) {
if let view = cameraView {
view.transform = CGAffineTransformScale(view.transform,
pinch.scale, pinch.scale)
pinch.scale = 1
}
}
これ以上コードを表示する必要があるかどうか教えてください。ありがとう!
私はカメラの実装で同じ問題を経験しました。これを解決するには、2つのことを知る必要があります。
AVCaptureDevice
のズームは変更していないためです。2つのことを変更するには、次のようなものが必要です。
func pinch(pinch: UIPinchGestureRecognizer) {
var device: AVCaptureDevice = self.videoDevice
var vZoomFactor = ((gestureRecognizer as! UIPinchGestureRecognizer).scale)
var error:NSError!
do{
try device.lockForConfiguration()
defer {device.unlockForConfiguration()}
if (vZoomFactor <= device.activeFormat.videoMaxZoomFactor){
device.videoZoomFactor = vZoomFactor
}else{
NSLog("Unable to set videoZoom: (max %f, asked %f)", device.activeFormat.videoMaxZoomFactor, vZoomFactor);
}
}catch error as NSError{
NSLog("Unable to set videoZoom: %@", error.localizedDescription);
}catch _{
}
}
ご覧のとおり、ビデオデバイスのクラス変数(videoDevice
)を使用して、ビジュアルコンポーネントに使用しているキャプチャデバイスを追跡しています。ズームを特定の範囲に制限し、ビュー自体ではなく、デバイスのズームプロパティを変更します。
1。ズームレベルを定義します。
let minimumZoom: CGFloat = 1.0
let maximumZoom: CGFloat = 3.0
var lastZoomFactor: CGFloat = 1.0
2。 CameraViewにピンチジェスチャを追加します。
let pinchRecognizer = UIPinchGestureRecognizer(target: self, action:#selector(pinch(_:)))
self.viewCamera.addGestureRecognizer(pinchRecognizer)
3。 zoomin
およびzoom out
のロジックを使用したピンチアクションメソッド
func pinch(_ pinch: UIPinchGestureRecognizer) {
guard let device = videoDeviceInput.device else { return }
// Return zoom value between the minimum and maximum zoom values
func minMaxZoom(_ factor: CGFloat) -> CGFloat {
return min(min(max(factor, minimumZoom), maximumZoom), device.activeFormat.videoMaxZoomFactor)
}
func update(scale factor: CGFloat) {
do {
try device.lockForConfiguration()
defer { device.unlockForConfiguration() }
device.videoZoomFactor = factor
} catch {
print("\(error.localizedDescription)")
}
}
let newScaleFactor = minMaxZoom(pinch.scale * lastZoomFactor)
switch pinch.state {
case .began: fallthrough
case .changed: update(scale: newScaleFactor)
case .ended:
lastZoomFactor = minMaxZoom(newScaleFactor)
update(scale: lastZoomFactor)
default: break
}
}
ありがとう。ハッピーコーディング????????
手動のzoomTo(2.0)関数が必要な場合は、これを使用できます
// Create listener for Pinch to Zoom
let pinchRecognizer = UIPinchGestureRecognizer(target: self, action:#selector(FSCameraView.pinchToZoom(_:)))
pinchRecognizer.delegate = self
self.previewViewContainer.addGestureRecognizer(pinchRecognizer)
// set the zoom to a zoomed in mode from start
setZoom(CGFloat(2.0)
// and the functions
func pinchToZoom(sender:UIPinchGestureRecognizer) {
var vZoomFactor = ((sender as! UIPinchGestureRecognizer).scale)
setZoom(vZoomFactor)
}
func setZoom(zoomFactor:CGFloat) {
var device: AVCaptureDevice = self.device!
var error:NSError!
do{
try device.lockForConfiguration()
defer {device.unlockForConfiguration()}
if (zoomFactor <= device.activeFormat.videoMaxZoomFactor) {
let desiredZoomFactor:CGFloat = zoomFactor + atan2(sender.velocity, 5.0);
device.videoZoomFactor = max(1.0, min(desiredZoomFactor, device.activeFormat.videoMaxZoomFactor));
}
else {
NSLog("Unable to set videoZoom: (max %f, asked %f)", device.activeFormat.videoMaxZoomFactor, zoomFactor);
}
}
catch error as NSError{
NSLog("Unable to set videoZoom: %@", error.localizedDescription);
}
catch _{
}
}
var device: AVCaptureDevice = self.backCamera
var vZoomFactor = sender.scale
var error:NSError!
do{
try device.lockForConfiguration()
defer {device.unlockForConfiguration()}
if (vZoomFactor <= device.activeFormat.videoMaxZoomFactor) {
let desiredZoomFactor:CGFloat = vZoomFactor + atan2(sender.velocity, 5.0);
device.videoZoomFactor = max(1.0, min(desiredZoomFactor, device.activeFormat.videoMaxZoomFactor));
}
else {
NSLog("Unable to set videoZoom: (max %f, asked %f)", device.activeFormat.videoMaxZoomFactor, vZoomFactor);
}
}
catch error as NSError{
NSLog("Unable to set videoZoom: %@", error.localizedDescription);
}
catch _{
}
Ritvik Upadhyaya'sの答えを拡張するには、前のズーム係数を保存して新しいズーム係数を計算する必要があります。指を離して試すたびにズームが通常にリセットされることは望ましくありません。再びズームします。
// To track the zoom factor
var prevZoomFactor: CGFloat = 1
func pinch(pinch: UIPinchGestureRecognizer) {
var device: AVCaptureDevice = self.videoDevice
// Here we multiply vZoomFactor with the previous zoom factor if it exist.
// Else just multiply by 1
var vZoomFactor = pinch.scale * prevZoomFactor
// If the pinching has ended, update prevZoomFactor.
// Note that we set the limit at 1, because zoom factor cannot be less than 1 or the setting device.videoZoomFactor will crash
if sender.state == .ended {
prevZoomFactor = zoomFactor >= 1 ? zoomFactor : 1
}
do {
try device.lockForConfiguration()
defer {device.unlockForConfiguration()}
if (vZoomFactor <= device.activeFormat.videoMaxZoomFactor) {
device.videoZoomFactor = vZoomFactor
} else {
print("Unable to set videoZoom: (max \(device.activeFormat.videoMaxZoomFactor), asked \(vZoomFactor))")
}
} catch {
print("\(error.localizedDescription)")
}
}
次のようにUIPinchGestureRecognizer.scale
を1にリセットするだけで、prevZoomFactor
の保存を回避できます。
@IBAction func pinchAction(_ sender: UIPinchGestureRecognizer) {
guard let device = currentCaptureDevice else {return}
var zoom = device.videoZoomFactor * sender.scale
sender.scale = 1.0
var error:NSError!
do{
try device.lockForConfiguration()
defer {device.unlockForConfiguration()}
if zoom >= device.minAvailableVideoZoomFactor && zoom <= device.maxAvailableVideoZoomFactor {
device.videoZoomFactor = zoom
}else{
NSLog("Unable to set videoZoom: (max %f, asked %f)", device.activeFormat.videoMaxZoomFactor, zoom);
}
}catch error as NSError{
NSLog("Unable to set videoZoom: %@", error.localizedDescription);
}catch _{
}
}
これは、ジェスチャーレコグナイザーが最初に登場したときに私が参加したWWDCイベントでAppleによって推奨されました。