我需要通过相机拍摄图像。但它出现以下错误:'NSInvalidArgumentException',原因:'无法直接实例化AVCaptureDevice。'
遵循以下代码:
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()
}
取回相机:
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
}
捕捉图片的事件:
@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)!)
}
}
}
处理图片:
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)
}
错误发生在这里:
input = AVCaptureDeviceInput(device: self.getBackCamera(), error: error)
答案 0 :(得分:2)
我一直在查找这个问题。您似乎无法实际实例化设备AVCaptureDevice对象。必须通过引用传递它。这就是我克服挑战的方式。 我没有实例化该类,我只是将其作为对AVCaptureDeviceInput对象的引用传递给它。
希望这有帮助!
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
}
}
}
}
答案 1 :(得分:0)
也许你在此期间解决了这个问题,但是如果你改变这样的代码它应该有效:
只需移除devic = AVCaptureDevice()
getBackCamera()
即可
并在类的头部声明如下: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
}