Commit 0486e49e by Daniel Dahan

CaptureView Example working with still image capture

parent b040107c
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_photo_camera_white.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ic_photo_camera_white@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ic_photo_camera_white@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_photo_camera_white_36pt.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ic_photo_camera_white_36pt@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ic_photo_camera_white_36pt@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
import UIKit import UIKit
import MaterialKit import MaterialKit
class ViewController: UIViewController { class ViewController: UIViewController, CaptureSessionDelegate {
private lazy var captureView: CaptureView = CaptureView() private lazy var captureView: CaptureView = CaptureView()
override func viewDidLoad() { override func viewDidLoad() {
...@@ -39,6 +39,11 @@ class ViewController: UIViewController { ...@@ -39,6 +39,11 @@ class ViewController: UIViewController {
:name: prepareCaptureView :name: prepareCaptureView
*/ */
private func prepareCaptureView() { private func prepareCaptureView() {
let navigationBarView: NavigationBarView = NavigationBarView()
navigationBarView.backgroundColor = MaterialColor.black.colorWithAlphaComponent(0.3)
navigationBarView.shadowDepth = .None
navigationBarView.statusBarStyle = .LightContent
let img1: UIImage? = UIImage(named: "ic_flash_auto_white") let img1: UIImage? = UIImage(named: "ic_flash_auto_white")
let btn1: FlatButton = FlatButton() let btn1: FlatButton = FlatButton()
btn1.pulseColor = nil btn1.pulseColor = nil
...@@ -51,14 +56,32 @@ class ViewController: UIViewController { ...@@ -51,14 +56,32 @@ class ViewController: UIViewController {
btn2.pulseColor = nil btn2.pulseColor = nil
btn2.setImage(img2, forState: .Normal) btn2.setImage(img2, forState: .Normal)
btn2.setImage(img2, forState: .Highlighted) btn2.setImage(img2, forState: .Highlighted)
let img3: UIImage? = UIImage(named: "ic_photo_camera_white_36pt")
let captureButton: FabButton = FabButton()
captureButton.backgroundColor = MaterialColor.grey.darken2
captureButton.borderWidth = .Border4
captureButton.borderColor = MaterialColor.white
captureButton.shadowDepth = .None
captureButton.setImage(img3, forState: .Normal)
captureButton.setImage(img3, forState: .Highlighted)
captureView.captureSession.delegate = self
captureView.captureButton = captureButton
captureView.flashAutoButton = btn1 captureView.flashAutoButton = btn1
captureView.switchCamerasButton = btn2 captureView.switchCamerasButton = btn2
captureView.navigationBarView.rightButtons = [btn1, btn2]
view.addSubview(captureView) view.addSubview(captureView)
captureView.translatesAutoresizingMaskIntoConstraints = false captureView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignToParent(view, child: captureView) MaterialLayout.alignToParent(view, child: captureView)
view.addSubview(captureButton)
captureButton.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromBottomRight(view, child: captureButton, bottom: 24, right: (view.bounds.width - 72) / 2)
MaterialLayout.size(view, child: captureButton, width: 72, height: 72)
view.addSubview(navigationBarView)
navigationBarView.rightButtons = [btn1, btn2]
} }
internal func handleFlash(sender: AnyObject) { internal func handleFlash(sender: AnyObject) {
...@@ -77,5 +100,17 @@ class ViewController: UIViewController { ...@@ -77,5 +100,17 @@ class ViewController: UIViewController {
captureView.flashAutoButton?.setImage(img, forState: .Normal) captureView.flashAutoButton?.setImage(img, forState: .Normal)
captureView.flashAutoButton?.setImage(img, forState: .Highlighted) captureView.flashAutoButton?.setImage(img, forState: .Highlighted)
} }
/**
:name: captureSessionFailedWithError
*/
func captureSessionFailedWithError(capture: CaptureSession, error: NSError) {
print(error)
}
func captureStillImageAsynchronously(capture: CaptureSession, image: UIImage?, error: NSError?) {
print(image)
print(error)
}
} }
...@@ -41,6 +41,11 @@ public protocol CaptureSessionDelegate { ...@@ -41,6 +41,11 @@ public protocol CaptureSessionDelegate {
:name: captureSessionFailedWithError :name: captureSessionFailedWithError
*/ */
optional func captureSessionFailedWithError(capture: CaptureSession, error: NSError) optional func captureSessionFailedWithError(capture: CaptureSession, error: NSError)
/**
:name: captureStillImageAsynchronously
*/
optional func captureStillImageAsynchronously(capture: CaptureSession, image: UIImage?, error: NSError?)
} }
@objc(CaptureSession) @objc(CaptureSession)
...@@ -244,6 +249,24 @@ public class CaptureSession : NSObject { ...@@ -244,6 +249,24 @@ public class CaptureSession : NSObject {
} }
/** /**
:name: sessionPreset
*/
public var currentVideoOrientation: AVCaptureVideoOrientation {
var orientation: AVCaptureVideoOrientation
switch UIDevice.currentDevice().orientation {
case .Portrait:
orientation = .Portrait
case .LandscapeRight:
orientation = .LandscapeLeft
case .PortraitUpsideDown:
orientation = .PortraitUpsideDown
default:
orientation = .LandscapeRight
}
return orientation
}
/**
:name: delegate :name: delegate
*/ */
public weak var delegate: CaptureSessionDelegate? public weak var delegate: CaptureSessionDelegate?
...@@ -420,6 +443,23 @@ public class CaptureSession : NSObject { ...@@ -420,6 +443,23 @@ public class CaptureSession : NSObject {
} }
/** /**
:name: captureStillImage
*/
public func captureStillImage() {
let connection: AVCaptureConnection = imageOutput.connectionWithMediaType(AVMediaTypeVideo)
connection.videoOrientation = currentVideoOrientation
imageOutput.captureStillImageAsynchronouslyFromConnection(connection) { (sampleBuffer: CMSampleBuffer!, error: NSError!) -> Void in
if nil == error {
let data: NSData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
self.delegate?.captureStillImageAsynchronously?(self, image: UIImage(data: data), error: nil)
} else {
self.delegate?.captureStillImageAsynchronously?(self, image: nil, error: error)
}
}
}
/**
:name: prepareSession :name: prepareSession
*/ */
private func prepareSession() { private func prepareSession() {
......
...@@ -35,16 +35,26 @@ public class CaptureView : MaterialView, CaptureSessionDelegate, CapturePreviewV ...@@ -35,16 +35,26 @@ public class CaptureView : MaterialView, CaptureSessionDelegate, CapturePreviewV
public private(set) lazy var exposureLayer: MaterialLayer = MaterialLayer() public private(set) lazy var exposureLayer: MaterialLayer = MaterialLayer()
/** /**
:name: navigationBarView :name: captureButton
*/ */
public private(set) lazy var navigationBarView: NavigationBarView = NavigationBarView() public var captureButton: UIButton? {
didSet {
if let v: UIButton = captureButton {
v.removeTarget(self, action: "handleCapture:", forControlEvents: .TouchUpInside)
v.addTarget(self, action: "handleCapture:", forControlEvents: .TouchUpInside)
} else {
captureButton?.removeFromSuperview()
captureButton = nil
}
}
}
/** /**
:name: flashAutoButton :name: flashAutoButton
*/ */
public var flashAutoButton: MaterialButton? { public var flashAutoButton: UIButton? {
didSet { didSet {
if let v: MaterialButton = flashAutoButton { if let v: UIButton = flashAutoButton {
v.removeTarget(self, action: "handleFlashAuto:", forControlEvents: .TouchUpInside) v.removeTarget(self, action: "handleFlashAuto:", forControlEvents: .TouchUpInside)
v.addTarget(self, action: "handleFlashAuto:", forControlEvents: .TouchUpInside) v.addTarget(self, action: "handleFlashAuto:", forControlEvents: .TouchUpInside)
} else { } else {
...@@ -57,9 +67,9 @@ public class CaptureView : MaterialView, CaptureSessionDelegate, CapturePreviewV ...@@ -57,9 +67,9 @@ public class CaptureView : MaterialView, CaptureSessionDelegate, CapturePreviewV
/** /**
:name: switchCamerasButton :name: switchCamerasButton
*/ */
public var switchCamerasButton: MaterialButton? { public var switchCamerasButton: UIButton? {
didSet { didSet {
if let v: MaterialButton = switchCamerasButton { if let v: UIButton = switchCamerasButton {
v.removeTarget(self, action: "handleSwitchCamera:", forControlEvents: .TouchUpInside) v.removeTarget(self, action: "handleSwitchCamera:", forControlEvents: .TouchUpInside)
v.addTarget(self, action: "handleSwitchCamera:", forControlEvents: .TouchUpInside) v.addTarget(self, action: "handleSwitchCamera:", forControlEvents: .TouchUpInside)
} else { } else {
...@@ -97,6 +107,13 @@ public class CaptureView : MaterialView, CaptureSessionDelegate, CapturePreviewV ...@@ -97,6 +107,13 @@ public class CaptureView : MaterialView, CaptureSessionDelegate, CapturePreviewV
} }
/** /**
:name: captureSession
*/
public var captureSession: CaptureSession {
return previewView.captureSession
}
/**
:name: init :name: init
*/ */
public convenience init() { public convenience init() {
...@@ -125,23 +142,6 @@ public class CaptureView : MaterialView, CaptureSessionDelegate, CapturePreviewV ...@@ -125,23 +142,6 @@ public class CaptureView : MaterialView, CaptureSessionDelegate, CapturePreviewV
addSubview(previewView) addSubview(previewView)
MaterialLayout.alignToParent(self, child: previewView) MaterialLayout.alignToParent(self, child: previewView)
addSubview(navigationBarView)
// var verticalFormat: String = "V:|"
// var views: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()
// var metrics: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()
// if 0 < views.count {
// addConstraints(MaterialLayout.constraint(verticalFormat, options: [], metrics: metrics, views: views))
// }
}
/**
:name: captureSessionFailedWithError
*/
public func captureSessionFailedWithError(capture: CaptureSession, error: NSError) {
print(error)
} }
/** /**
...@@ -194,23 +194,29 @@ public class CaptureView : MaterialView, CaptureSessionDelegate, CapturePreviewV ...@@ -194,23 +194,29 @@ public class CaptureView : MaterialView, CaptureSessionDelegate, CapturePreviewV
public override func prepareView() { public override func prepareView() {
super.prepareView() super.prepareView()
preparePreviewView() preparePreviewView()
prepareNavigationBarView()
prepareFocusLayer() prepareFocusLayer()
prepareExposureLayer() prepareExposureLayer()
reloadView() reloadView()
} }
/** /**
:name: handleCapture
*/
internal func handleCapture(button: UIButton) {
previewView.captureSession.captureStillImage()
}
/**
:name: handleSwitchCamera :name: handleSwitchCamera
*/ */
internal func handleSwitchCamera(button: MaterialButton) { internal func handleSwitchCamera(button: UIButton) {
previewView.captureSession.switchCameras() previewView.captureSession.switchCameras()
} }
/** /**
:name: handleFlashAuto :name: handleFlashAuto
*/ */
internal func handleFlashAuto(button: MaterialButton) { internal func handleFlashAuto(button: UIButton) {
switch previewView.captureSession.flashMode { switch previewView.captureSession.flashMode {
case .Off: case .Off:
previewView.captureSession.flashMode = .On previewView.captureSession.flashMode = .On
...@@ -225,20 +231,10 @@ public class CaptureView : MaterialView, CaptureSessionDelegate, CapturePreviewV ...@@ -225,20 +231,10 @@ public class CaptureView : MaterialView, CaptureSessionDelegate, CapturePreviewV
} }
/** /**
:name: prepareNavigationBarView
*/
private func prepareNavigationBarView() {
navigationBarView.backgroundColor = MaterialColor.black.colorWithAlphaComponent(0.3)
navigationBarView.shadowDepth = .None
navigationBarView.statusBarStyle = .LightContent
}
/**
:name: preparePreviewView :name: preparePreviewView
*/ */
private func preparePreviewView() { private func preparePreviewView() {
previewView.translatesAutoresizingMaskIntoConstraints = false previewView.translatesAutoresizingMaskIntoConstraints = false
previewView.captureSession.delegate = self
previewView.delegate = self previewView.delegate = self
previewView.captureSession.startSession() previewView.captureSession.startSession()
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment