[iOS 7] 追加された画像フィルタ郡 (2) pixel値の多項式補正フィルタ

2013.09.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

iOS7で追加されたフィルタに、パラメータによって、かなり細かく画像を加工できるようになっています。
今回も、例のごとく、下記の写真を使って、フィルタがどんな効果があるかを見ていってみましょう。

original

例のごとく、9月1日に鷲宮で行われた土師祭の写真です。なお、真ん中右側で祭ハッピで浮かれてるのは知人です。

CIColorClamp

 指定された色相の範囲内に色値を変更するフィルター。
色値をCIVectorで指定することで、その色値内に留めることが可能です。
パラメータとして、min値とmax値を指定します。
なお、このmin値のデフォルトは[0 0 0 0]で、max値が[1 1 1 1]となりますが、何も指定しない場合はこのデフォルト値が使われます。
では、デフォルトであえて指定しなかったときはどうなるかを見てみましょう。

colorclamp_def

はい、見事なまでに入力されたものと一緒です。
とりあえず、このパラメータを[0.2 0.2 0.2 0.2]と[0.8 0.8 0.8 0.8]にしてフィルタかけてみましょう。
プログラムのソースコードは次のとおりです。

/* ファイルを読み込む */
CIImage *ciImage = [[CIImage alloc] initWithImage:[UIImage imageNamed:@"original.jpg"]];

/* フィルタを読み込む */
CIFilter *ciFilter = [CIFilter filterWithName:@"CIColorClamp" keysAndValues:kCIInputImageKey, ciImage, nil];

/* オプション */
[ciFilter setValue:[CIVector vectorWithX:0.2 Y:0.2 Z:0.2 W:0.2] forKey:@"inputMinComponents"];
[ciFilter setValue:[CIVector vectorWithX:0.8 Y:0.8 Z:0.8 W:0.8] forKey:@"inputMaxComponents"];

/* フィルタした内容を画面に表示する */
CIContext *ciContext = [CIContext contextWithOptions:nil];
CGImageRef cgimg = [ciContext createCGImage:[ciFilter outputImage] fromRect:[[ciFilter outputImage] extent]];
_mainImage.image = [UIImage imageWithCGImage:cgimg scale:1.0f orientation:UIImageOrientationUp];
CGImageRelease(cgimg);

colorclamp_0.2_0.8

全体的に白っぽくなりましたね。こういうフィルタらしいです。
他の値でもやってみましょう。
せっかくなので、[0.4 0 0.4 0]と[0.8 1 0.8 1]を指定してみます。

colorclamp_0.4_0.8

赤みがかったけど、全体的に白っぽいフィルタになりました。この数値をいじるだけで、いろんな補正ができそうですね。

CIColorCrossPolynomial

画像内の画素値を変更するフィルタです。
具体的に書くと、rgbの画素値を計算値によって変換するフィルタだったりします。
・・・全然具体的でもないですしわかりづらいですね。
とりあえず計算式を書いておくと、以下の様な感じです。

out.r = in.r * rC[0] + in.g * rC[1] + in.b * rC[2] + in.r * in.r * rC[3] + in.g * in.g * rC[4] + in.b * in.b * rC[5] + in.r * in.g * rC[6] + in.g * in.b * rC[7] + in.b * in.r * rC[8] + rC[9];

ソースコードは以下のとおりです。

/* ファイルを読み込む */
CIImage *ciImage = [[CIImage alloc] initWithImage:[UIImage imageNamed:@"original.jpg"]];

/* フィルタを読み込む */
CIFilter *ciFilter = [CIFilter filterWithName:@"CIColorCrossPolynomial" keysAndValues:kCIInputImageKey, ciImage, nil];

/* オプション */
CGFloat r[10] = {1.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
CGFloat g[10] = {0.0f, 1.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
CGFloat b[10] = {0.0f, 0.0f, 1.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
[ciFilter setValue:
     [CIVector vectorWithValues:r count:10] forKey:@"inputRedCoefficients"];
[ciFilter setValue:
     [CIVector vectorWithValues:g count:10] forKey:@"inputGreenCoefficients"];
[ciFilter setValue:
     [CIVector vectorWithValues:b count:10] forKey:@"inputBlueCoefficients"];

/* フィルタした内容を画面に表示する */
CIContext *ciContext = [CIContext contextWithOptions:nil];
CGImageRef cgimg = [ciContext createCGImage:[ciFilter outputImage] fromRect:[[ciFilter outputImage] extent]];
_mainImage.image = [UIImage imageWithCGImage:cgimg scale:1.0f orientation:UIImageOrientationUp];
CGImageRelease(cgimg);

このパラメータで出てきた画像は次のようになります。

ColorCrossPolynomial_1

どこかで見たことのあるフィルタになりました。そう、前の(1)でのポラロイド写真風のフィルタで使用していたものにどことなく似た結果です。
それもそのはず、そのフィルタの内部ではこのフィルタを使っているそうです。
設定値によっては、より詳細にできるということですね。

これでは面白く無いので、位相をずらしてみましょう。
ソースコードを以下のように変更します。

CGFloat r[10] = {0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
CGFloat g[10] = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
CGFloat b[10] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};

すると、画像は次のようになりました。

ColorCrossPolynomial_2

こういった、画像をおもちゃに遊ぶこともできるし、いろいろ出来る機能が、今回のiOS7からOS標準で実装された便利な機能です。