その後のその後

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

Core Image の全エフェクトを試せるサンプルコードを公開しました

Core Image のフィルタ(画像にエフェクトをかけたり、色を調整したりするもの)を一通り試せるサンプルプロジェクトをgithubに上げました。


というか、これ、1年以上前にアップしてこちらの記事に書いたのですが、ほとんど認知されることがなかったので、改めて紹介させていただきます。


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






プロジェクト一式、こちらからダウンロードできます。
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型のパラメータだけを取り出し、

for (NSString *key in editableAttributes) {
    
    NSDictionary *attributeDictionary = [editableAttributes objectForKey:key];

    if ([[attributeDictionary objectForKey:kCIAttributeClass] isEqualToString:@"NSNumber"]) {

        // 後述    
    }   
}


BOOL/Decimal/Integerそれぞれの型に応じて、ランダム値を設定しています。
(下記は、上記コードのif文の中身)

        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];
        }

Core Image の参考書籍

iOS Core Frameworksテクニカルガイド

iOS Core Frameworksテクニカルガイド
Shawn Welch
インプレスジャパン
売り上げランキング: 242494


2012年9月と比較的最近出版されたものですが、原著の出版は2011年9月。したがって iOS5 時代のものです。『Core Image』の章があるのですが、広く浅く、という感じです。

iOS5プログラミングブック

iOS5プログラミングブック
加藤 寛人 吉田 悠一 藤川 宏之 西方 夏子 関川 雄介 高丘 知央
インプレスジャパン
売り上げランキング: 88968


Core Imageの章あり。この本は全体的に説明が詳しく、あまり他の書籍やブログにないところまで踏み込んだ情報も多いので、個人的にはこちらの方がおすすめです。

おまけ:CIFilterのフィルタ名一覧(iOS 6 版)

前回記事(2011年11月)時点では 48 個だったものが、なんと 94 個に増えていました。


CIAdditionCompositing
CIAffineClamp
CIAffineTile
CIAffineTransform
CIBarsSwipeTransition
CIBlendWithMask
CIBloom
CIBumpDistortion
CIBumpDistortionLinear
CICheckerboardGenerator
CICircleSplashDistortion
CICircularScreen
CIColorBlendMode
CIColorBurnBlendMode
CIColorControls
CIColorCube
CIColorDodgeBlendMode
CIColorInvert
CIColorMap
CIColorMatrix
CIColorMonochrome
CIColorPosterize
CIConstantColorGenerator
CICopyMachineTransition
CICrop
CIDarkenBlendMode
CIDifferenceBlendMode
CIDisintegrateWithMaskTransition
CIDissolveTransition
CIDotScreen
CIEightfoldReflectedTile
CIExclusionBlendMode
CIExposureAdjust
CIFalseColor
CIFlashTransition
CIFourfoldReflectedTile
CIFourfoldRotatedTile
CIFourfoldTranslatedTile
CIGammaAdjust
CIGaussianBlur
CIGaussianGradient
CIGlideReflectedTile
CIGloom
CIHardLightBlendMode
CIHatchedScreen
CIHighlightShadowAdjust
CIHoleDistortion
CIHueAdjust
CIHueBlendMode
CILanczosScaleTransform
CILightenBlendMode
CILightTunnel
CILinearGradient
CILineScreen
CILuminosityBlendMode
CIMaskToAlpha
CIMaximumComponent
CIMaximumCompositing
CIMinimumComponent
CIMinimumCompositing
CIModTransition
CIMultiplyBlendMode
CIMultiplyCompositing
CIOverlayBlendMode
CIPinchDistortion
CIPixellate
CIRadialGradient
CIRandomGenerator
CISaturationBlendMode
CIScreenBlendMode
CISepiaTone
CISharpenLuminance
CISixfoldReflectedTile
CISixfoldRotatedTile
CISmoothLinearGradient
CISoftLightBlendMode
CISourceAtopCompositing
CISourceInCompositing
CISourceOutCompositing
CISourceOverCompositing
CIStarShineGenerator
CIStraightenFilter
CIStripesGenerator
CISwipeTransition
CITemperatureAndTint
CIToneCurve
CITriangleKaleidoscope
CITwelvefoldReflectedTile
CITwirlDistortion
CIUnsharpMask
CIVibrance
CIVignette
CIVortexDistortion
CIWhitePointAdjust