2015-09-03 52 views
8

è possibile applicare il filtro AVLayer e aggiungerlo al vista come addSublayer? Voglio cambiare i colori e aggiungere un po 'di rumore al video dalla fotocamera usando Swift e non so come.Come applicare il filtro video in tempo reale usando Swift

ho pensato, che è possibile aggiungere filterLayer e previewLayer come questo:

self.view.layer.addSublayer(previewLayer) 
self.view.layer.addSublayer(filterLayer) 

e questo può forse creare un video con il mio filtro personalizzato, ma penso, che è possibile farlo in modo più efficace usign AVComposition

Così che cosa ho bisogno di sapere:

  1. Qual è il modo più semplice per applicare il filtro all'uscita video della videocamera in tempo reale?
  2. È possibile unire AVCaptureVideoPreviewLayer e CALayer?

Grazie per ogni suggerimento ..

+0

Non hai fornito molte informazioni su ciò che stai facendo, ma è possibile modificare il feed video dal vivo usando un 'GLKView' invece di un' AVCapturePreviewLayer' e applicando il filtro a ciascun frame in 'captureOutput (capptureOutput: didOutputToSampleBuffer: dalla connessioneConnection:) '. –

+0

Grazie! GLKView mi sembra migliore. :) Semplicemente: ho bisogno di applicare il filtro ai frame video dal vivo e ho la possibilità di salvarlo su un file. Sto facendo una specie di videocamera con filtri. –

risposta

21

C'è un'altra alternativa, utilizzare un AVCaptureSession per creare istanze di CIImage a cui è possibile applicare CIFilters (di cui ci sono carichi, da sfocature di correzione del colore per VFX).

Ecco un esempio utilizzando l'effetto ComicBook. In poche parole, creare un AVCaptureSession:

let captureSession = AVCaptureSession() 
captureSession.sessionPreset = AVCaptureSessionPresetPhoto 

Crea un AVCaptureDevice per rappresentare la fotocamera, qui sto impostando la fotocamera posteriore:

let backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) 

quindi creare una concreta attuazione del dispositivo e collegare lo alla sessione. In Swift 2, istanziare AVCaptureDeviceInput può generare un errore, quindi abbiamo bisogno di cogliere che:

do 
{ 
    let input = try AVCaptureDeviceInput(device: backCamera) 

    captureSession.addInput(input) 
} 
catch 
{ 
    print("can't access camera") 
    return 
} 

Ora, ecco un po 'Gotcha': anche se in realtà non usiamo un AVCaptureVideoPreviewLayer ma è necessario per ottenere il campione deleghiamo a lavorare, in modo creiamo uno di quelli:

// although we don't use this, it's required to get captureOutput invoked 
let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 

view.layer.addSublayer(previewLayer) 

successivo, creiamo un'uscita video, AVCaptureVideoDataOutput che useremo per accedere al feed video:

let videoOutput = AVCaptureVideoDataOutput() 

Garantire che l'auto implementa AVCaptureVideoDataOutputSampleBufferDelegate, siamo in grado di impostare il delegato tampone campione sulla uscita video:

videoOutput.setSampleBufferDelegate(self, 
    queue: dispatch_queue_create("sample buffer delegate", DISPATCH_QUEUE_SERIAL)) 

L'uscita video viene poi attaccato alla sessione di cattura:

captureSession.addOutput(videoOutput) 

...e, infine, iniziamo la sessione di cattura:

captureSession.startRunning() 

Perché abbiamo impostato il delegato, captureOutput sarà invocato con ogni cattura frame. captureOutput viene passato un tampone di tipo CMSampleBuffer e ci vogliono solo due righe di codice per convertire i dati per un CIImage per Core Image per gestire:

let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) 
let cameraImage = CIImage(CVPixelBuffer: pixelBuffer!) 

... e che i dati immagine viene passato al nostro Comic Book effetto, che, a sua volta, viene utilizzata per popolare la visualizzazione di un'immagine:

let comicEffect = CIFilter(name: "CIComicEffect") 

comicEffect!.setValue(cameraImage, forKey: kCIInputImageKey) 

let filteredImage = UIImage(CIImage: comicEffect!.valueForKey(kCIOutputImageKey) as! CIImage!) 

dispatch_async(dispatch_get_main_queue()) 
{ 
    self.imageView.image = filteredImage 
} 

ho la source code for this project available in my GitHub repo here.

+1

Grazie mille! I tuoi articoli e repo mi aiutano davvero. Ma ho un errore, quando provo a creare dispatch_queue 'Non posso invocare 'setSampleBufferDelegate' con un elenco di argomenti di tipo '(ViewController, queue: dispatch_queue_attr_t!)'' –

+0

Grazie per le gentili parole! Date un'occhiata a questa classe: https://github.com/FlexMonkey/ParticleCam/blob/master/ParticleCam/ViewController.swift –

+1

Hah, colpa mia ... Stavo usando iOS 8.4.1 Quindi problema risolto. Grazie ancora. –