Jak zastosować filtr do wideo w czasie rzeczywistym za pomocą Swift

Czy można zastosować filtr do AVLayer i dodać go do view jako addSublayer ? Chcę zmienić kolory i dodać trochę szumu do wideo z kamery za pomocą Swift i nie wiem jak.

Pomyślałem, że można dodać filterLayer i previewLayer tak:

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

I to może stworzyć film z moim niestandardowym filtrem, ale myślę, że jest to możliwe, aby zrobić to bardziej efektywnie. AVComposition

Więc co Muszę wiedzieć:

  1. jaki jest najprostszy sposób zastosowania filtra do wyjścia wideo kamery w czasie rzeczywistym?
  2. czy można połączyć AVCaptureVideoPreviewLayer i CALayer ?
Dzięki za każdą sugestię..
Author: David Sýkora, 2015-09-03

1 answers

Istnieje inna alternatywa, użyj AVCaptureSession, aby utworzyć instancje CIImage, do których możesz zastosować filtry Cifilter (których są ładunki, od rozmycia, przez korekcję kolorów po VFX).

Oto przykład użycia efektu ComicBook. W skrócie, Utwórz avcapturesession:

let captureSession = AVCaptureSession()
captureSession.sessionPreset = AVCaptureSessionPresetPhoto

Utwórz AVCaptureDevice do reprezentowania kamery, tutaj ustawiam tylną kamerę:

let backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)

Następnie stwórz konkretną implementację urządzenia i przymocuj ją do sesja. W języku Swift 2 utworzenie instancji AVCaptureDeviceInput może spowodować błąd, więc musimy go wychwycić:

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

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

Oto mała 'mam cię': chociaż w rzeczywistości nie używamy AVCaptureVideoPreviewLayer, ale jest on wymagany do działania przykładowego delegata, więc tworzymy jeden z nich: {]}

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

view.layer.addSublayer(previewLayer)

Następnie tworzymy wyjście wideo, AVCaptureVideoDataOutput, którego użyjemy, aby uzyskać dostęp do kanału wideo:

let videoOutput = AVCaptureVideoDataOutput()

Zapewnienie, że samo wdraża AVCaptureVideoDataOutputSampleBufferdelegate, możemy ustawić delegat bufora próbki na wyjściu wideo:

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

Wyjście wideo jest następnie dołączane do sesji przechwytywania:

 captureSession.addOutput(videoOutput)

...i na koniec zaczynamy sesję przechwytywania:

captureSession.startRunning()

Ponieważ ustawiliśmy delegata, captureOutput będzie wywoływany przy każdym przechwytywaniu klatki. captureOutput jest przekazywany bufor przykładowy typu CMSampleBuffer i wystarczy dwie linie kodu, aby przekonwertować te dane do CIImage dla rdzenia Obraz do obsługi:

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

...i te dane obrazu są przekazywane do naszego efektu komiksu, który z kolei jest używany do wypełniania widoku obrazu: {]}

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
}

Mam kod źródłowy tego projektu dostępny w moim repo GitHub tutaj .

 22
Author: Simon Gladman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-03 16:32:47