簡體   English   中英

如何將CIFilter輸出到Camera視圖?

[英]How to output a CIFilter to a Camera view?

我剛剛開始使用Objective-C,我正在嘗試創建一個簡單的應用程序,它會顯示帶有模糊效果的攝像機視圖。 我讓Camera輸出與AVFoundation框架一起工作。 現在,我正在嘗試連接核心圖像框架,但不知道如何,Apple文檔讓我感到困惑,在線搜索指南和教程導致沒有結果。 在此先感謝您的幫助。

#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

這是讓你入門的東西。 這是以下鏈接的代碼的更新版本。
https://gist.github.com/eladb/9662102

訣竅是使用AVCaptureVideoDataOutputSampleBufferDelegate
使用此委托,您可以使用imageWithCVPixelBuffer從相機緩沖區構建CIImage

現在雖然我想弄清楚如何減少滯后。 我會盡快更新。


更新:延遲現在很小,並且有些效果不明顯。 不幸的是,模糊似乎是最慢的之一。 您可能想要查看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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM