Compare commits

...

4 Commits
master ... zoom

Author SHA1 Message Date
Ricardo Torrão c1d6fd5abf Saves still images with Zoom 2016-01-29 18:21:02 +00:00
Ricardo Torrão 5f94c9b898 Pinch to Zoom 2016-01-26 16:05:21 +00:00
Ricardo Torrão 93c9920a65 Merge branch 'zoom' of github.com:imaginary-cloud/CameraManager into zoom
# Conflicts:
#	camera.xcodeproj/project.xcworkspace/xcuserdata/nataliaterlecka.xcuserdatad/UserInterfaceState.xcuserstate
#	camera/CameraManager.swift
2016-01-26 10:07:54 +00:00
Natalia Terlecka eb4e77d2bb cameraIsReady property and addPreviewLayerToView competition block. 2015-12-24 09:52:39 +01:00
5 changed files with 145 additions and 49 deletions

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/> <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies> </dependencies>
<objects> <objects>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="bhK-VL-qY4"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="bhK-VL-qY4">
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/> <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies> </dependencies>
<scenes> <scenes>

View File

@ -31,7 +31,7 @@ public enum CameraOutputQuality: Int {
} }
/// Class for handling iDevices custom camera usage /// Class for handling iDevices custom camera usage
public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate { public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate, UIGestureRecognizerDelegate {
// MARK: - Public properties // MARK: - Public properties
@ -58,6 +58,9 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
/// Property to determine if manager should write the resources to the phone library. Default value is true. /// Property to determine if manager should write the resources to the phone library. Default value is true.
public var writeFilesToPhoneLibrary = true public var writeFilesToPhoneLibrary = true
/// Property to determine if manager allows zoom. Default value is true.
public var enableZoom = true
/// Property to determine if manager should follow device orientation. Default value is true. /// Property to determine if manager should follow device orientation. Default value is true.
public var shouldRespondToOrientationChanges = true { public var shouldRespondToOrientationChanges = true {
didSet { didSet {
@ -139,6 +142,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
if cameraIsSetup { if cameraIsSetup {
if cameraOutputMode != oldValue { if cameraOutputMode != oldValue {
_setupOutputMode(cameraOutputMode, oldCameraOutputMode: oldValue) _setupOutputMode(cameraOutputMode, oldCameraOutputMode: oldValue)
_setupMaxZoom()
} }
} }
} }
@ -188,9 +192,14 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
} catch { } } catch { }
} }
return NSURL(string: tempPath)! return NSURL(string: tempPath)!
}() }()
private var pinchToZoom: UIPinchGestureRecognizer?
private var zoomScale: CGFloat = 1.0
private var beginZoomScale: CGFloat = 1.0
private var maxZoomFactor: CGFloat = 1.0
// MARK: - CameraManager // MARK: - CameraManager
/** /**
@ -340,7 +349,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
} }
imageCompletition(UIImage(data: imageData), nil) imageCompletition(UIImage(data: imageData), nil)
} }
}) })
}) })
} else { } else {
_show(NSLocalizedString("Capture session output mode video", comment:""), message: NSLocalizedString("I can't take any picture", comment:"")) _show(NSLocalizedString("Capture session output mode video", comment:""), message: NSLocalizedString("I can't take any picture", comment:""))
@ -436,8 +445,47 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
} }
} }
// MARK: - UIGestureRecognizerDelegate
public func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer.isKindOfClass(UIPinchGestureRecognizer) {
beginZoomScale = zoomScale;
}
return true
}
func _handlePinchGesture(pinchRecognizer: UIPinchGestureRecognizer) {
var allTouchesAreOnThePreviewLayer = true
let numTouches = pinchRecognizer.numberOfTouches();
for index in 0..<numTouches {
let location: CGPoint = pinchRecognizer.locationOfTouch(index, inView: embedingView)
let convertedLocation: CGPoint = (embedingView?.convertPoint(location, fromCoordinateSpace: (embedingView?.superview)!))!
if ((embedingView?.pointInside(convertedLocation, withEvent: nil)) == nil) {
allTouchesAreOnThePreviewLayer = false
break
}
}
if allTouchesAreOnThePreviewLayer {
_updateZoomScale(pinchRecognizer.scale)
_applyZoomScale()
}
}
// MARK: - CameraManager() // MARK: - CameraManager()
private func _updateZoomScale(scale: CGFloat) {
zoomScale = max(1.0, min(beginZoomScale * scale, maxZoomFactor))
}
private func _updateTorch(flashMode: CameraFlashMode) { private func _updateTorch(flashMode: CameraFlashMode) {
captureSession?.beginConfiguration() captureSession?.beginConfiguration()
let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)
@ -499,6 +547,9 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
captureSession?.addOutput(stillImageOutput) captureSession?.addOutput(stillImageOutput)
captureSession?.commitConfiguration() captureSession?.commitConfiguration()
} }
stillImageOutput!.connectionWithMediaType(AVMediaTypeVideo)?.videoScaleAndCropFactor = zoomScale
return stillImageOutput! return stillImageOutput!
} }
@ -506,7 +557,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
var currentConnection: AVCaptureConnection?; var currentConnection: AVCaptureConnection?;
switch cameraOutputMode { switch cameraOutputMode {
case .StillImage: case .StillImage:
currentConnection = stillImageOutput?.connectionWithMediaType(AVMediaTypeVideo) currentConnection = _getStillImageOutput().connectionWithMediaType(AVMediaTypeVideo)
case .VideoOnly, .VideoWithMic: case .VideoOnly, .VideoWithMic:
currentConnection = _getMovieOutput().connectionWithMediaType(AVMediaTypeVideo) currentConnection = _getMovieOutput().connectionWithMediaType(AVMediaTypeVideo)
} }
@ -553,6 +604,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
validCaptureSession.beginConfiguration() validCaptureSession.beginConfiguration()
validCaptureSession.sessionPreset = AVCaptureSessionPresetHigh validCaptureSession.sessionPreset = AVCaptureSessionPresetHigh
self._updateCameraDevice(self.cameraDevice) self._updateCameraDevice(self.cameraDevice)
self._setupPinchToZoom()
self._setupOutputs() self._setupOutputs()
self._setupOutputMode(self.cameraOutputMode, oldCameraOutputMode: nil) self._setupOutputMode(self.cameraOutputMode, oldCameraOutputMode: nil)
self._setupPreviewLayer() self._setupPreviewLayer()
@ -585,6 +637,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
private func _addPreviewLayerToView(view: UIView) { private func _addPreviewLayerToView(view: UIView) {
embedingView = view embedingView = view
dispatch_async(dispatch_get_main_queue(), { () -> Void in dispatch_async(dispatch_get_main_queue(), { () -> Void in
guard let _ = self.previewLayer else { guard let _ = self.previewLayer else {
return return
@ -614,6 +667,19 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
} }
} }
private func _setupMaxZoom() {
if cameraDevice == .Back {
if let maxZoom = backCameraDevice?.activeFormat.videoMaxZoomFactor {
maxZoomFactor = maxZoom
}
}
else {
if let maxZoom = frontCameraDevice?.activeFormat.videoMaxZoomFactor {
maxZoomFactor = maxZoom
}
}
}
private func _setupOutputMode(newCameraOutputMode: CameraOutputMode, oldCameraOutputMode: CameraOutputMode?) { private func _setupOutputMode(newCameraOutputMode: CameraOutputMode, oldCameraOutputMode: CameraOutputMode?) {
captureSession?.beginConfiguration() captureSession?.beginConfiguration()
@ -623,6 +689,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
case .StillImage: case .StillImage:
if let validStillImageOutput = stillImageOutput { if let validStillImageOutput = stillImageOutput {
captureSession?.removeOutput(validStillImageOutput) captureSession?.removeOutput(validStillImageOutput)
_removePinchToZoom()
} }
case .VideoOnly, .VideoWithMic: case .VideoOnly, .VideoWithMic:
if let validMovieOutput = movieOutput { if let validMovieOutput = movieOutput {
@ -642,6 +709,7 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
} }
if let validStillImageOutput = stillImageOutput { if let validStillImageOutput = stillImageOutput {
captureSession?.addOutput(validStillImageOutput) captureSession?.addOutput(validStillImageOutput)
_addPinchToZoom()
} }
case .VideoOnly, .VideoWithMic: case .VideoOnly, .VideoWithMic:
captureSession?.addOutput(_getMovieOutput()) captureSession?.addOutput(_getMovieOutput())
@ -792,6 +860,28 @@ public class CameraManager: NSObject, AVCaptureFileOutputRecordingDelegate {
} }
} }
private func _setupPinchToZoom() {
pinchToZoom = UIPinchGestureRecognizer(target: self, action: "_handlePinchGesture:")
pinchToZoom!.delegate = self
}
private func _addPinchToZoom() {
embedingView?.addGestureRecognizer(pinchToZoom!)
}
private func _removePinchToZoom() {
embedingView?.removeGestureRecognizer(pinchToZoom!)
}
private func _applyZoomScale() {
let affineTransform = CGAffineTransformMakeScale(zoomScale, zoomScale)
CATransaction.begin()
CATransaction.setAnimationDuration(0.025)
embedingView?.transform = affineTransform
CATransaction.commit()
}
deinit { deinit {
stopAndRemoveCaptureSession() stopAndRemoveCaptureSession()
_stopFollowingDeviceOrientation() _stopFollowingDeviceOrientation()

View File

@ -59,6 +59,11 @@
"idiom" : "ipad", "idiom" : "ipad",
"size" : "76x76", "size" : "76x76",
"scale" : "2x" "scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
} }
], ],
"info" : { "info" : {