web-dev-qa-db-fra.com

Comment capturer une image avec AVCaptureSession dans Swift?

J'ai un UIViewController dans lequel j'utilise AVCaptureSession pour montrer la caméra et cela fonctionne très bien et rapidement. J'ai placé un objet UIButton au-dessus de cette vue de la caméra et ajouté un IBAction pour le bouton.

Voici à quoi ça ressemble maintenant:

my camera app

Maintenant, je veux obtenir l'image de la vue actuelle de la caméra lorsque l'utilisateur appuie sur le bouton:

@IBAction func takePicture(sender: AnyObject) {
    // omg, what do do?!
}

Je n'ai aucune idée de comment je peux faire ça. J'imaginais qu'il pourrait y avoir quelque chose comme:

let captureSession = AVCaptureSession()
var myDearPicture = captureSession.takePicture() as UIImage // something like it?

Le lien complet pour le code du contrôleur est ici https://Gist.github.com/rodrigoalvesvieira/392d683435ee29305059 , espérons que cela aide

39
rodrigoalves

Exemple AVCaptureSession

import UIKit
import AVFoundation
class ViewController: UIViewController {
    let captureSession = AVCaptureSession()
    let stillImageOutput = AVCaptureStillImageOutput()
    var error: NSError?
    override func viewDidLoad() {
        super.viewDidLoad()
        let devices = AVCaptureDevice.devices().filter{ $0.hasMediaType(AVMediaTypeVideo) && $0.position == AVCaptureDevicePosition.Back }
        if let captureDevice = devices.first as? AVCaptureDevice  {

            captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &error))
            captureSession.sessionPreset = AVCaptureSessionPresetPhoto
            captureSession.startRunning()
            stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]
            if captureSession.canAddOutput(stillImageOutput) {
                captureSession.addOutput(stillImageOutput)
            }
            if let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) {
                previewLayer.bounds = view.bounds
                previewLayer.position = CGPointMake(view.bounds.midX, view.bounds.midY)
                previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
                let cameraPreview = UIView(frame: CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height))
                cameraPreview.layer.addSublayer(previewLayer)
                cameraPreview.addGestureRecognizer(UITapGestureRecognizer(target: self, action:"saveToCamera:"))
                view.addSubview(cameraPreview)
            }
        }
    }
    func saveToCamera(sender: UITapGestureRecognizer) {
        if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo) {
            stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection) {
                (imageDataSampleBuffer, error) -> Void in
                let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
                 UIImageWriteToSavedPhotosAlbum(UIImage(data: imageData), nil, nil, nil)
            }
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

Exemple UIImagePickerController

import UIKit

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    let imagePicker = UIImagePickerController()
    @IBOutlet weak var imageViewer: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
            dismissViewControllerAnimated(true, completion: nil)
             imageViewer.image = image
    }
    @IBAction func presentImagePicker(sender: AnyObject) {

        if UIImagePickerController.isCameraDeviceAvailable( UIImagePickerControllerCameraDevice.Front) {

            imagePicker.delegate = self
            imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
            presentViewController(imagePicker, animated: true, completion: nil)

        }
    }
}
94
Leo Dabus

Comme AVCaptureStillImageOutput est obsolète, j'ai créé un autre exemple Swift d'utilisation de AVCaptureSession et de AVCapturePhotoOutput dans iOS 10. Vérifiez ceci dehors.

7
Lawliet