Utiliser la caméra dans une application iOS (3/3)

Dans l’article précédent, nous avons vu comment utiliser AVCaptureSession et AVCapturePhotoOutput pour prendre une photo.

Voyons comment utiliser la classe AVCaptureVideoOutput. Alors que AVCapturePhotoOutput offre une fonction capturePhoto, dans le cas de AVCaptureVideoOutput, le delegate permet d’accéder à un buffer avec la fonction captureOutput(_ output: AVCaptureOutput, didOutput...) qui est appelée à chaque fois qu’une nouvelle image est disponible.

Préparer la Capture Session

La captureSession est paramétrée de la même manière que dans le projet précédent, mais à la place de AVCapturePhotoOutput, nous créons un AVCaptureVideoOutput :

    let videoOutput = AVCaptureVideoDataOutput()
    videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
    captureSession.addOutput(videoOutput)

Avec l’affectation du delegate, nous devons créer une DispatchQueue. La capture vidéo s’effectue toujours sur un thread séparé. Dans les fonctions du delegate, nous ne sommes donc pas dans le main thread.

Récupérer une image du flux vidéo

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
 
        guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
            return
        }
        let ciImage = CIImage(cvImageBuffer: imageBuffer).oriented(.right)
 
        // maj captureView dans le main thread
        DispatchQueue.main.async {
            self.captureView.image = UIImage(ciImage: ciImage)
        }
}

Le buffer nous renvoie un objet CVImageBuffer qui peut être converti en CIImage, le format image de Core Image, qui à son tour peut être traduit en UIImage pour l’affichage. L’affectation d’une image à une view doit toujours se fait dans le main thread.

Pourquoi faire une capture d’image via un flux vidéo ? Pour faire de la reconnaissance d’image en temps réel, ce que je détaillerai dans un prochain article.

Le code source de cet article est disponible ici.