iOSのカメラでリアルタイムフィルターするのにCIFilterは向かないって話。

処理遅いっぽい。リアルタイムフィルターには向かないっぽいけど、画像にフィルター書けるのは、とても気軽に出来る。

リアルタイムにフィルターかけるのはGPUImageが爆速らしいので、後日触る。

カメラの起動

AVFoundationでカメラを表示するとても短いサンプル #Objective-C - Qiita [キータ]

これのコードコピペしました。

フィルターかける

CoreImage.framework必要なので追加する

CIFilterの使い方!みたいな記事の多くは、[CIFilter filterWithName:keysAndValues:]を使ってるけど、若干分かりにくいので、フィルターに必要なパラメタの設定はKVC使ってKeyとValueの設定しています。

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    UIImage *rawCaptureImage = [self imageFromSampleBufferRef:sampleBuffer];
    UIImage *filterImage = nil; // ここでフィルター関数呼ぶ感じの想定
}

セピア

intensityはどのくらいEffectをかけるかの割合。最小0.0f、最大1.0f

+ (UIImage *)sepiaToneFilterWithImage:(UIImage *)srcImage intensity:(float)intensity {
    CIImage *ciImage = [[CIImage alloc] initWithImage:srcImage];
    CIFilter *ciFilter = [CIFilter filterWithName:@"CISepiaTone"];
    [ciFilter setValue:ciImage forKey:kCIInputImageKey];
    [ciFilter setValue:@(intensity) forKey:[NSString stringWithFormat:@"inputIntensity"]];

    CIContext *ciContext = [CIContext contextWithOptions:nil];
    CGImageRef cgImageRef = [ciContext createCGImage:[ciFilter outputImage] fromRect:[[ciFilter outputImage] extent]];
    UIImage *filteringImage = [UIImage imageWithCGImage:cgImageRef scale:1.0f orientation:UIImageOrientationUp];
    CGImageRelease(cgImageRef);

    return filteringImage;
}

色の反転

+ (UIImage *)colorInvertWithImage:(UIImage *)srcImage {
    CIImage *ciImage = [[CIImage alloc] initWithImage:srcImage];
    CIFilter *ciFilter = [CIFilter filterWithName:@"CIColorInvert"];
    [ciFilter setValue:ciImage forKey:kCIInputImageKey];

    CIContext *ciContext = [CIContext contextWithOptions:nil];
    CGImageRef cgImageRef = [ciContext createCGImage:[ciFilter outputImage] fromRect:[[ciFilter outputImage] extent]];
    UIImage *filteringImage = [UIImage imageWithCGImage:cgImageRef scale:1.0f orientation:UIImageOrientationUp];
    CGImageRelease(cgImageRef);

    return filteringImage;
}

ポスタライズ

inputLevelsはどのくらいポスタライズするか!最小0.0f、最大30.0f

+ (UIImage *)posterizeWithImage:(UIImage *)srcImage inputLevels:(float)inputLevels {
    CIImage *ciImage = [[CIImage alloc] initWithImage:srcImage];
    CIFilter *ciFilter = [CIFilter filterWithName:@"CIColorPosterize"];
    [ciFilter setValue:ciImage forKey:kCIInputImageKey];
    [ciFilter setValue:@(inputLevels) forKey:[NSString stringWithFormat:@"inputLevels"]];

    CIContext *ciContext = [CIContext contextWithOptions:nil];
    CGImageRef cgImageRef = [ciContext createCGImage:[ciFilter outputImage] fromRect:[[ciFilter outputImage] extent]];
    UIImage *filteringImage = [UIImage imageWithCGImage:cgImageRef scale:1.0f orientation:UIImageOrientationUp];
    CGImageRelease(cgImageRef);

    return filteringImage;
}

あと色々あるけど、公式のドキュメント読んだほうが早い気がする。

Core Image Programming Guide

凄く古いけど嬉しいことに日本語ドキュメントです。