Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
261 views
in Technique[技术] by (71.8m points)

iphone - Capture picture from iOS camera

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)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...