2015-04-17 14 views
8

Właśnie zaczynam w Objective-C i staram się stworzyć prostą aplikację, która pokazuje widok z kamery z efektem rozmycia na nim. Dostałem wyjście Camera działające w ramach AVFoundation. Teraz próbuję podłączyć Core Image Framework, ale nie wiem jak to zrobić, dokumentacja Apple jest myląca dla mnie i wyszukiwanie przewodników i tutoriali online prowadzi do braku wyników. Z góry dziękuję za pomoc.Jak wyprowadzić CIFilter do widoku z kamery?

#import "ViewController.h" 
#import <AVFoundation/AVFoundation.h> 
@interface ViewController() 

@property (strong ,nonatomic) CIContext *context; 

@end 

@implementation ViewController 
AVCaptureSession *session; 
AVCaptureStillImageOutput *stillImageOutput; 

-(CIContext *)context 
{ 
    if(!_context) 
    { 
     _context = [CIContext contextWithOptions:nil]; 
    } 
    return _context; 
} 
- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
} 

-(void)viewWillAppear:(BOOL)animated{ 
    session = [[AVCaptureSession alloc] init]; 
    [session setSessionPreset:AVCaptureSessionPresetPhoto]; 

    AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    NSError *error; 
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error]; 

    if ([session canAddInput:deviceInput]) { 
     [session addInput:deviceInput]; 
    } 

    AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session]; 
    [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 
    CALayer *rootLayer = [[self view] layer]; 
    [rootLayer setMasksToBounds:YES]; 
    CGRect frame = self.imageView.frame; 

    [previewLayer setFrame:frame]; 

    [previewLayer.connection setVideoOrientation:AVCaptureVideoOrientationLandscapeRight]; 


    [rootLayer insertSublayer:previewLayer atIndex:0]; 

    stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; 
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil]; 
    [stillImageOutput setOutputSettings:outputSettings]; 

    [session addOutput:stillImageOutput]; 

    [session startRunning];  
} 
@end 

Odpowiedz

10

Oto coś, od czego zacząć. To jest zaktualizowana wersja kodu z poniższego linku.
https://gist.github.com/eladb/9662102

Sztuką jest wykorzystanie AVCaptureVideoDataOutputSampleBufferDelegate.
Za pomocą tego uczestnika można użyć imageWithCVPixelBuffer, aby skonstruować CIImage z bufora aparatu.

W tej chwili jednak staram się dowiedzieć, jak zmniejszyć opóźnienie. Zaktualizuję jak najszybciej.


Aktualizacja: Opóźnienie jest teraz minimalne, a na niektórych efektach niezauważalne. Niestety wydaje się, że rozmycie jest jedną z najwolniejszych. Możesz zajrzeć do vImage.


#import "ViewController.h" 
#import <CoreImage/CoreImage.h> 
#import <AVFoundation/AVFoundation.h> 

@interface ViewController() { 

} 

@property (strong, nonatomic) CIContext *coreImageContext; 
@property (strong, nonatomic) AVCaptureSession *cameraSession; 
@property (strong, nonatomic) AVCaptureVideoDataOutput *videoOutput; 
@property (strong, nonatomic) UIView *blurCameraView; 
@property (strong, nonatomic) CIFilter *filter; 
@property BOOL cameraOpen; 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.blurCameraView = [[UIView alloc]initWithFrame:[[UIScreen mainScreen] bounds]]; 
    [self.view addSubview:self.blurCameraView]; 

    //setup filter 
    self.filter = [CIFilter filterWithName:@"CIGaussianBlur"]; 
    [self.filter setDefaults]; 
    [self.filter setValue:@(3.0f) forKey:@"inputRadius"]; 

    [self setupCamera]; 
    [self openCamera]; 
    // Do any additional setup after loading the view, typically from a nib. 
} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

- (void)setupCamera 
{ 
    self.coreImageContext = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @(YES)}]; 

    // session 
    self.cameraSession = [[AVCaptureSession alloc] init]; 
    [self.cameraSession setSessionPreset:AVCaptureSessionPresetLow]; 
    [self.cameraSession commitConfiguration]; 

    // input 
    AVCaptureDevice *shootingCamera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    AVCaptureDeviceInput *shootingDevice = [AVCaptureDeviceInput deviceInputWithDevice:shootingCamera error:NULL]; 
    if ([self.cameraSession canAddInput:shootingDevice]) { 
     [self.cameraSession addInput:shootingDevice]; 
    } 

    // video output 
    self.videoOutput = [[AVCaptureVideoDataOutput alloc] init]; 
    self.videoOutput.alwaysDiscardsLateVideoFrames = YES; 
    [self.videoOutput setSampleBufferDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)]; 
    if ([self.cameraSession canAddOutput:self.videoOutput]) { 
     [self.cameraSession addOutput:self.videoOutput]; 
    } 

    if (self.videoOutput.connections.count > 0) { 
     AVCaptureConnection *connection = self.videoOutput.connections[0]; 
     connection.videoOrientation = AVCaptureVideoOrientationPortrait; 
    } 

    self.cameraOpen = NO; 
} 

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { 
    // Get a CMSampleBuffer's Core Video image buffer for the media data 
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

    // turn buffer into an image we can manipulate 
    CIImage *result = [CIImage imageWithCVPixelBuffer:imageBuffer]; 

    // filter 
    [self.filter setValue:result forKey:@"inputImage"]; 

    // render image 
    CGImageRef blurredImage = [self.coreImageContext createCGImage:self.filter.outputImage fromRect:result.extent]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     self.blurCameraView.layer.contents = (__bridge id)blurredImage; 
     CGImageRelease(blurredImage); 
    }); 
} 

- (void)openCamera { 
    if (self.cameraOpen) { 
     return; 
    } 

    self.blurCameraView.alpha = 0.0f; 
    [self.cameraSession startRunning]; 
    [self.view layoutIfNeeded]; 

    [UIView animateWithDuration:3.0f animations:^{ 

     self.blurCameraView.alpha = 1.0f; 

    }]; 

    self.cameraOpen = YES; 
} 
+0

Wow. W porządku! przetestuje to. Dzięki! –

+0

Jak to zrobić w przypadku nagrywania tego samego filmu wideo? –

Powiązane problemy