Reputation: 1213
I need to capture an image through the camera. But it gives the following error: 'NSInvalidArgumentException', reason: 'Cannot instantiate a AVCaptureDevice directly.'
Follows the code:
var session: AVCaptureSession!
var device: AVCaptureDevice!
var captureVideoPreviewLayer: AVCaptureVideoPreviewLayer!
var image: UIImage!
var input: AVCaptureDeviceInput!
var stillImageOutput: AVCaptureStillImageOutput!
var viewControllerScheduling: RentalSchedulingViewController!
override func viewDidLoad() {
super.viewDidLoad()
session = AVCaptureSession()
session.sessionPreset = AVCaptureSessionPresetPhoto;
captureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
captureVideoPreviewLayer.frame = self.view.frame
self.view.layer.addSublayer(captureVideoPreviewLayer)
var error = NSErrorPointer()
captureVideoPreviewLayer.session.beginConfiguration()
input = AVCaptureDeviceInput(device: self.getBackCamera(), error: error)
session.addInput(input)
captureVideoPreviewLayer.session.commitConfiguration()
stillImageOutput = AVCaptureStillImageOutput()
var outputSettings = NSDictionary(objectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey)
stillImageOutput.outputSettings = outputSettings
session.addOutput(stillImageOutput)
session.startRunning()
}
Get back camera:
func getBackCamera() -> AVCaptureDevice {
var devic = AVCaptureDevice()
let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as NSArray
for dev in devices {
devic = dev as AVCaptureDevice
if devic.position == AVCaptureDevicePosition.Back {
return devic
}
}
return devic
}
Event to capture image:
@IBAction func capture(sender: AnyObject) {
var videoConnection = AVCaptureConnection()
for con in stillImageOutput.connections {
let connection = con as AVCaptureConnection
for p in connection.inputPorts {
let port = p as AVCaptureInputPort
if port.mediaType == AVMediaTypeVideo {
videoConnection = connection
break;
}
}
}
stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection) {
(imageSampleBuffer, error) in
if imageSampleBuffer != nil {
let imageData = AVCaptureStillImageOutput .jpegStillImageNSDataRepresentation(imageSampleBuffer)
self.processImage(UIImage(data: imageData)!)
}
}
}
The processment image:
func processImage(image: UIImage) {
UIGraphicsBeginImageContext(CGSizeMake(320, 426));
image.drawInRect(CGRectMake(0, 0, 320, 426))
let smallImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
let cropRect = CGRectMake(0, 55, 320, 320)
let imageRef = CGImageCreateWithImageInRect(smallImage.CGImage, cropRect)
self.image = UIImage(CGImage: imageRef)
}
the error occurs right here:
input = AVCaptureDeviceInput(device: self.getBackCamera(), error: error)
Upvotes: 0
Views: 1202
Reputation: 210
Maybe you solve it in the meantime, but if you change your code like this it should work:
Just remove the devic = AVCaptureDevice()
in your getBackCamera()
and make the declaration in the head of the class like this: var device, devic : AVCaptureDevice!
class ViewController: UIViewController {
var session: AVCaptureSession!
var device, devic : AVCaptureDevice!
var captureVideoPreviewLayer: AVCaptureVideoPreviewLayer!
var image: UIImage!
var input: AVCaptureDeviceInput!
var stillImageOutput: AVCaptureStillImageOutput!
//var viewControllerScheduling: RentalSchedulingViewController!
override func viewDidLoad() {
super.viewDidLoad()
session = AVCaptureSession()
session.sessionPreset = AVCaptureSessionPresetPhoto;
captureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
captureVideoPreviewLayer.frame = self.view.frame
self.view.layer.addSublayer(captureVideoPreviewLayer)
var error = NSErrorPointer()
captureVideoPreviewLayer.session.beginConfiguration()
input = AVCaptureDeviceInput(device: self.getBackCamera(), error: error)
session.addInput(input)
captureVideoPreviewLayer.session.commitConfiguration()
stillImageOutput = AVCaptureStillImageOutput()
var outputSettings = NSDictionary(objectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey)
stillImageOutput.outputSettings = outputSettings as [NSObject : AnyObject]
session.addOutput(stillImageOutput)
session.startRunning()
}
func getBackCamera() -> AVCaptureDevice {
// devic = AVCaptureDevice()
let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as NSArray
for dev in devices {
devic = dev as! AVCaptureDevice
if devic.position == AVCaptureDevicePosition.Back {
return devic
}
}
return devic
}
Upvotes: 0
Reputation: 237
I've been looking up this issue. It seems that you can't actually instantiate the device AVCaptureDevice object. have to pass it by reference. This is how I overcame the challenge. I didn't instantiate the class I simply passed it in as a reference to the AVCaptureDeviceInput Object.
Hope this helped!
var captureDevice : AVCaptureDevice?
let devices = AVCaptureDevice.devices()
// Loop through all the capture devices on this phone
for device in devices {
// Make sure this particular device supports video
if (device.hasMediaType(AVMediaTypeVideo)) {
// Finally check the position and confirm we've got the back camera
if(device.position == AVCaptureDevicePosition.Back) {
captureDevice = device as? AVCaptureDevice
}
}
}
}
Upvotes: 2