2016-04-28 5 views
0

を向上させる私がイメージにセピアフィルタを適用するには、次のコードを書いた:私はこのコードを実行するとObjective CのCIImageフィルタスピード

- (void)applySepiaFilter { 
    // Set previous image 
    NSData *buffer = [NSKeyedArchiver archivedDataWithRootObject: self.mainImage.image]; 
    [_images push:[NSKeyedUnarchiver unarchiveObjectWithData: buffer]]; 


    UIImage* u = self.mainImage.image; 
    CIImage *image = [[CIImage alloc] initWithCGImage:u.CGImage]; 
    CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone" 
            keysAndValues: kCIInputImageKey, image, 
         @"inputIntensity", @0.8, nil]; 
    CIImage *outputImage = [filter outputImage]; 
    self.mainImage.image = [self imageFromCIImage:outputImage]; 
} 

- (UIImage *)imageFromCIImage:(CIImage *)ciImage { 
    CIContext *ciContext = [CIContext contextWithOptions:nil]; 
    CGImageRef cgImage = [ciContext createCGImage:ciImage fromRect:[ciImage extent]]; 
    UIImage *image = [UIImage imageWithCGImage:cgImage]; 
    CGImageRelease(cgImage); 
    return image; 
} 

1~2秒間遅れているようです。コア・イメージはコア・グラフィックスよりも速いと聞きましたが、私はレンダリング時間に大きな影響を受けません。 CoreGraphicsやOpenCV(これはプロジェクトのどこかで使用されている)でさえ処理が速いのかどうか疑問に思っていましたか?そうでない場合は、このコードを最適化してより速く実行できますか?

+0

ここで実際に何が遅いのか調べるためにInstrumentsを使用しましたか? – zneak

+0

@zneakこれらの楽器はどのようなものでしょうか? –

+0

"Time Profiler"のようなものです。 – zneak

答えて

3

イメージのサイズに応じて、コアイメージを使用するよりもコアグラフィックスの方が遅くなることはほとんど保証できます。画像が小さい場合、Core Graphicsは問題ありませんが、処理が大量であれば、GPUを使用したレンダリングよりもはるかに遅くなります。

コアイメージは非常に高速ですが、何が起こっているのか非常に意識していなければなりません。 Core Imageのパフォーマンスの大半は、コンテキストの設定とCore Imageとの間でのイメージのコピーが原因です。バイトをコピーするだけでなく、Core Imageは画像フォーマット間で変換することもあります。

  • がCIContextの作成:

    あなたのコードは、次のすべての時間をやっています。 (遅い)

  • CGImageからバイトを取り、CIImageを作成します。
  • GPUへの画像データのコピー(低速)。
  • 処理セピアフィルタ(高速)。
  • 結果イメージをCGImageにコピーします。 (遅い)

これはピークパフォーマンスのレシピではありません。 CGImageのバイトは通常CPUメモリに保存されますが、Core Imageはその処理にGPUを使用したいと考えています。 CIContextオブジェクトあなたがレンダリングするたびに作成しないでください

  • :パフォーマンスの考慮事項については

    優れたリファレンスは、コアイメージのためGetting the Best Performanceドキュメントで提供されています。 コンテキストには多くの状態情報が格納されます。それらを再利用する方が効率的です。

  • アプリにカラー管理が必要かどうかを評価します。あなたがそれを必要としない限り使用しないでください。 「あなたのアプリケーションにはカラー管理が必要ですか?」を参照してください。
  • GPUコンテキストでCIImageオブジェクトをレンダリングしているときに、コアアニメーションアニメーションを使用しないでください。 両方を同時に使用する必要がある場合は、CPUを使用するように両方を設定できます。

  • 画像がCPUとGPUの制限を超えないようにしてください。 (iOS)

  • 可能であれば、より小さい画像を使用してください。 パフォーマンスは出力ピクセルの数に比例します。 Core Imageに、より小さなビュー、テクスチャ、またはフレームバッファをレンダリングさせることができます。コアアニメーションのサイズを上げて表示する。

  • CGImageCreateWithImageInRect関数やCGImageSourceCreateThumbnailAtIndex関数などの、コアグラフィックスまたはイメージI/O関数を使用してクロップまたはダウンサンプリングします。

  • UIImageViewクラスは、静的イメージで最も効果的です。 アプリのパフォーマンスを最高にする必要がある場合は、下位レベルのAPIを使用します。

  • CPUとGPU間の不要なテクスチャ転送を避ける。 内容の倍率を適用する前に、ソースイメージと同じサイズの四角形にレンダリングします。

  • アルゴリズムフィルタに似た結果を生成する簡単なフィルタを使用することを検討してください。 たとえば、CIColorCubeはCISepiaToneと同様の出力を生成し、より効率的に出力できます。

  • iOS 6.0以降のYUVイメージのサポートを活用してください。

あなたはリアルタイム処理性能を要求する場合は、CoreImageは、その出力をレンダリングすることができOpenGLのビューを使用すると、あなたのイメージを読み込みますCGImageからそれを引っ張ってGPUに直接バイトの代わりに、 。 GLKViewを使用し、drawRect:を上書きすることは、Core Imageが直接レンダリングできるビューを取得するためのかなり簡単なソリューションです。 Core Imageから最高のパフォーマンスを引き出すには、GPUにデータを保存することが最善の方法です。

可能な限り再利用してください。その後のレンダリングのために(ドキュメントのように)CIContextの周りを保つ。 OpenGLビューを使用すると、できるだけ再利用したいこともあります。

ソフトウェアレンダリングを使用すると、パフォーマンスを向上させることもできます。ソフトウェアのレンダリングは、GPUとのコピーを避けるでしょう。 [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer: @(YES)}]しかし、CPUレンダリングは通常GPUレンダリングよりも遅いため、これは実際のレンダリングでパフォーマンスの制限があります。

したがって、パフォーマンスを最大限に高める難易度を選択できます。最高のパフォーマンスはより難しいかもしれませんが、ごくわずかな変更により、あなたのユースケースに対して「許容できる」パフォーマンスが得られる場合があります。