その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

CIFilter の効果を一通り試せるサンプルコード(フィルタ名一覧つき)

iOS5から使えるようになった CIFilter の効果を一通り試せるサンプルプロジェクトをgithubに上げました。


こんな感じでフィルターを試せます。
(フィルタのパラメータはランダムに生成されるので、かける度に変わる場合もあります)






プロジェクト一式、こちらからダウンロードできます。
https://github.com/shu223/FilterDemo


注意点として、選んでも何も起こらないフィルターがたくさんあります
詳細は後述しますが、こちら、Apple の PocketCoreImage というサンプルコードを数行いじっただけのものなので、あんまり多種多様なフィルタに対応したつくりになってはいないのです。。
そういうフィルタはリストから除いてもよかったのですが、「どんなフィルタがあるのか?」を一覧できる意味もあるので、残してあります。

PocketCoreImageからの改変点

CIFilterは、下記のように、NSString型の名前を引数に渡してインスタンスを生成します。

CIFilter *newFilter = [CIFilter filterWithName:name];


で、ここに渡せる名前をずらずらっと列挙するために、awakeFromNibで次のようなコードで全ビルトインフィルタの名前を取得しています。

NSArray *filterNames;
filterNames = [CIFilter filterNamesInCategory:kCICategoryBuiltIn];
_availableFilters = [NSArray arrayWithArray:filterNames];

それと、PocketCoreImageでは、フィルタをかける箇所で、次のようにKVCを利用して元画像をフィルタに渡しています。

[filter setValue:_filteredImage forKey:@"inputImage"];


ここで、inputImageというアクセサを持たないフィルタもあるので、

if (![filter respondsToSelector:NSSelectorFromString(@"inputImage")]) {
    continue;
}

とチェックを入れて例外を回避しています。
(詳細はこちらの記事をご参照ください)


その他、コードの解説

もともと PocketCoreImage にあった部分なのですが、多種多様なパラメータを持つフィルタに対してランダム値を設定する部分はこうなっているよ、というのを紹介させていただきます。

  • CIFilterのattributesメソッドでパラメータ一覧を取得

(このあとここでは設定しないパラメータを取り除く処理が入りますが割愛)

NSDictionary *filterAttributes = [filter attributes];
  • NSNumber型のパラメータだけを取り出し、BOOL/Decimal/Integerそれぞれの型に応じたランダム値を設定
for (NSString *key in editableAttributes) {
    
    NSDictionary *attributeDictionary = [editableAttributes objectForKey:key];

    if ([[attributeDictionary objectForKey:kCIAttributeClass] isEqualToString:@"NSNumber"]) {
    
        // The number types are further broken down into sub types.  For our purposes, we
        // can group them into types that require either a boolean, float, or integer.
        if ([attributeDictionary objectForKey:kCIAttributeType] == kCIAttributeTypeBoolean)
        {
            NSInteger randomValue = (rand() % 2); 
            
            NSLog(@"Setting %i for key %@ of type BOOL", randomValue, key);
            [filter setValue:[NSNumber numberWithInteger:randomValue] forKey:key];
        }
        else if([attributeDictionary objectForKey:kCIAttributeType] == kCIAttributeTypeScalar ||
                [attributeDictionary objectForKey:kCIAttributeType] == kCIAttributeTypeDistance ||
                [attributeDictionary objectForKey:kCIAttributeType] == kCIAttributeTypeAngle)
        {
            // Get the min and max values
            float maximumValue = [[attributeDictionary valueForKey:kCIAttributeSliderMax] floatValue];
            float minimumValue = [[attributeDictionary valueForKey:kCIAttributeSliderMin] floatValue];
            
            float randomValue = randFloat(minimumValue, maximumValue);

            NSLog(@"Setting %f for key %@ of type Decimal", randomValue, key);
            [filter setValue:[NSNumber numberWithFloat:randomValue] forKey:key];
        }
        else
        {
            // Get the min and max values
            NSInteger maximumValue = [[attributeDictionary valueForKey:kCIAttributeMax] integerValue];
            NSInteger minimumValue = [[attributeDictionary valueForKey:kCIAttributeMin] integerValue];
            
            NSInteger randomValue = (rand() % (maximumValue - minimumValue)) + minimumValue;
            
            NSLog(@"Setting %i for key %@ of type Integer", randomValue, key);
            [filter setValue:[NSNumber numberWithInteger:randomValue] forKey:key];
        }
    
    }
    
}

おまけ:CIFilterのフィルタ名一覧

CIAdditionCompositing
CIAffineTransform
CICheckerboardGenerator
CIColorBlendMode
CIColorBurnBlendMode
CIColorControls
CIColorCube
CIColorDodgeBlendMode
CIColorInvert
CIColorMatrix
CIColorMonochrome
CIConstantColorGenerator
CICrop
CIDarkenBlendMode
CIDifferenceBlendMode
CIExclusionBlendMode
CIExposureAdjust
CIFalseColor
CIGammaAdjust
CIGaussianGradient
CIHardLightBlendMode
CIHighlightShadowAdjust
CIHueAdjust
CIHueBlendMode
CILightenBlendMode
CILinearGradient
CILuminosityBlendMode
CIMaximumCompositing
CIMinimumCompositing
CIMultiplyBlendMode
CIMultiplyCompositing
CIOverlayBlendMode
CIRadialGradient
CISaturationBlendMode
CIScreenBlendMode
CISepiaTone
CISoftLightBlendMode
CISourceAtopCompositing
CISourceInCompositing
CISourceOutCompositing
CISourceOverCompositing
CIStraightenFilter
CIStripesGenerator
CITemperatureAndTint
CIToneCurve
CIVibrance
CIVignette
CIWhitePointAdjust