ぴよログ

↓に移転したのでこっちは更新されません、多分。

UIImageの色相をフィルターで変えるには

移転しました →

iOSのアプリを開発していてこんな要望がありました。

「撮影した写真を半透明にした上で色を少し変えて出したいから、ちょうどいい値を探したい」

どの程度半透明にするかはalpha値に対応したスライダーをおけばいいなというのはすぐにわかりましたが、色を変えるってどうやんの?と。

結論を言えば、CoreImageのフィルターを使えば余裕でした。

CIFilterを使って色を変える

色を変えると言ってもいろいろありますが、ここでは全体的な色合いを赤っぽくしたり青っぽくしたり、といったことを意味します。CIFilterを使って色相を調整するのがこれにあたります。

  1. UIImageからCIImageを作る
  2. CIImageと各種パラメータを渡したCIFiterを作る
  3. CGImageを取り出す
  4. UIImageに直す

一般的に色相は色相環という輪っかで表現されます。

そのためCIFilterで色相を調整するときも-3.14〜3.14の範囲でパラメータを指定できます。

今回は値の範囲が-3.14〜3.14のスライダーを配置し、スライダーの値が変わったときのイベントで元画像にフィルターをかけてUIImageViewに設定し直すという方法を取ります。

これで先方の要望である、ちょうどいい値を探すという目的に合ったスライダーを実装することができました。

ソース

- (IBAction)hueChanged:(UISlider *)sender {
    UIImage* image = [UIImage imageNamed:@"image.png"];
   
    CIImage *ciImage = [[CIImage alloc] initWithImage:image];
    CIFilter *ciFilter = [CIFilter filterWithName:@"CIHueAdjust"
                                    keysAndValues:kCIInputImageKey, ciImage,
                                    @"inputAngle",[NSNumber numberWithFloat:sender.value], nil];

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

    self.imageView.image = newImage;
} 

結果

こんな感じ。

リアルタイム処理に使うには少々重いのですが、検証用ということで細かいことは考えていません。