我用这个代码来拍照片,我不能尽快拍到照片。快速拍摄多张照片,应用程序就会崩溃。
我用的是Swift 1.1。
错误:
由于异常“NSInvalidArgumentException”终止应用程序,原因:‘+AVCaptureStillImageOutput:- NULL示例缓冲区。’。
class ViewController: UIViewController {
let captureSession = AVCaptureSession()
var previewLayer : AVCaptureVideoPreviewLayer?
var captureDevice : AVCaptureDevice?
var captureConnection: AVCaptureConnection?
var stillImageOutput = AVCaptureStillImageOutput()
let targetRegion = CALayer()
var currentImage: UIImage?
@IBOutlet weak var cameraView: UIImageView!
@IBOutlet weak var imageDisplayed: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.setNavigationBarHidden(true, animated: true)
captureSession.sessionPreset = AVCaptureSessionPreset1920x1080
let devices = AVCaptureDevice.devices()
for device in devices {
if device.hasMediaType(AVMediaTypeVideo) {
if device.position == AVCaptureDevicePosition.Back {
captureDevice = device as? AVCaptureDevice
}
}
}
if captureDevice != nil {
println("Device trovato")
beginSession()
}
}
func beginSession() {
var err: NSError? = nil
captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &err))
if err != nil {
println("err \(err?.localizedDescription)")
return
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
self.view.layer.addSublayer(previewLayer)
previewLayer?.frame = CGRect(x: cameraView.frame.origin.x, y: cameraView.frame.origin.y, width: cameraView.frame.size.width, height: cameraView.frame.size.height)
captureSetup()
captureSession.startRunning()
}
func captureSetup() {
let outputSetting = NSDictionary(dictionary: [AVVideoCodecKey: AVVideoCodecJPEG])
self.stillImageOutput.outputSettings = outputSetting
self.captureSession.addOutput(stillImageOutput)
for connection:AVCaptureConnection in self.stillImageOutput.connections as [AVCaptureConnection] {
for port:AVCaptureInputPort in connection.inputPorts! as [AVCaptureInputPort] {
if port.mediaType == AVMediaTypeVideo {
captureConnection = connection as AVCaptureConnection
break
}
}
if captureConnection != nil {
break
}
}
}
var i = 0;
func captureScene() {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
if self.captureConnection != nil {
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, _) -> Void in
let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
var pickedImage: UIImage = UIImage(data:imageDataJpeg)!
if let data = UIImagePNGRepresentation(pickedImage) {
let filename = self.getDocumentsDirectory().stringByAppendingPathComponent("\(self.i).png")
data.writeToFile(filename, atomically: true)
self.i++
}
})
}
})
}
func getDocumentsDirectory() -> NSString {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory: AnyObject = paths[0]
return documentsDirectory as NSString
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
captureScene()
}
}发布于 2015-12-01 19:01:15
@alper在linked answer中解释的是,有时imageSampleBuffer可以是零,这就是崩溃的根源。
我相信在Swift 2中imageSampleBuffer是一个可选的,所以为了避免这种崩溃,您可以检查为零。示例:
if imageSampleBuffer != nil {
let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
// ...
} else {
// handle or ignore the error
}但是您使用的是Swift 1,这是一个问题,因为在Swift 1中,imageSampleBuffer被声明为一个隐式未包装的可选选项,这意味着它不能是零,并且不能像前面的示例那样检查。
@alper给出的解决方案是使用
CMSampleBufferIsValid(imageSampleBuffer)作为检查缓冲区是否有效的方法。
如果前面的解决方案不起作用,您可以尝试这样做。
当我查看函数签名时:
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, _) -> Void in我看到缓冲区旁边有另一个参数,但是您忽略了它:
(imageSampleBuffer:CMSampleBuffer!,_)
我没有查找Swift 1文档,但是如果_实际上是一个错误参数,我不会感到惊讶。尝试用error替换它,如下所示:
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, error) -> Void in或者也许
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, error:NSError) -> Void in然后在继续使用error之前检查imageSampleBuffer的内容。
注意:正如我最后说过的,使用error__的解决方案是猜测,我没有测试:您必须尝试,调整,看看我的想法是否正确。如果您能够找到Swift 1的文档,并明确地告诉我们有关它的情况,那将是非常理想的。
https://stackoverflow.com/questions/34024942
复制相似问题