2014-11-13 4 views
0

Мне нужно захватить изображение через камеру. Но он дает следующую ошибку: «NSInvalidArgumentException», причина: «Невозможно создать экземпляр AVCaptureDevice напрямую».Захват изображения с камеры iOS

Следит код:

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)!) 
      } 
     } 
    } 

processment изображение:

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) 
+1

Вы случайно испытываете на симуляторе, или используете ли вы настоящее устройство с камерой? –

+0

Тестирование на реальном устройстве – Gian

ответ

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 
      } 
     } 
    } 

} 
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 
} 
Смежные вопросы