6

を に変換する必要がありCIImageますCGImage。これは私が現在使用しているコードです:

CGImageRef img = [myContext createCGImage:ciImage fromRect:[ciImage extent]];

しかし、彼のコード行は、通常のサイズの画像では非常に遅くなります。適切に使用できるようにするには、かなり遅くなります。CIImagesこれらをに変換する別のより高速な方法はありCGImagesますか?

最後に、Core Graphicsを に描画するために使用しCGImagesますCGContextCIImagesに直接描画する方法があれば、CGContextそれも高速になるはずです。これは可能ですか?

ありがとう

4

2 に答える 2

9

CIImageのドキュメントから:

CIImage オブジェクトには画像データが関連付けられていますが、画像ではありません。CIImage オブジェクトは、イメージの「レシピ」と考えることができます。CIImage オブジェクトには、画像を生成するために必要なすべての情報が含まれていますが、Core Image は、そうするように指示されるまで、実際には画像をレンダリングしません。この「遅延評価」方式により、Core Image は可能な限り効率的に動作することができます。

これは、適用した (またはより適切に適用するように要求された)フィルタリングCIImageは、画像をレンダリングするまで実際には発生しないことを意味しますCGImageRef。それがおそらく、速度低下を経験している理由です。

とはいえ、フィルタリングCIImageは一般的に非常に高速なプロセスであるため、画像サイズに基づいて低速の定義を提供する必要があります.

最後に、ボトルネックが実際にあると思われる場所にあることを確認するには、Instruments を使用してアプリケーションをプロファイリングする必要があります。

編集

カラー フィルターを適用して、iPad3 のデバイス カメラ (960x540) からの画像ストリームをフィルター処理するサンプル プロジェクトを作成しようとしましたが、CIColorMap60fps (~16ms) を超えています。

CIContextアプリケーションによっては、ColorMapFilter、 、inputGradientImage(時間の経過とともに変化しない場合)を再利用し、inputImage反復ごとにのみを更新することで、パフォーマンスを向上させることができます。

たとえば、一度呼び出してから、処理するすべてのフレームをprepareFrameFiltering繰り返し呼び出します。applyFilterToFrame:

@property (nonatomic, strong) CIContext *context;
@property (nonatomic, strong) CIFilter *colorMapFilter;

- (void)prepareFrameFiltering {
    self.context = [CIContext contextWithOptions:nil];
    CIImage *colorMap = [CIImage imageWithCGImage:[UIImage imageNamed:@"gradient.jpg"].CGImage];
    self.colorMapFilter = [CIFilter filterWithName:@"CIColorMap"];
    [self.colorMapFilter setValue:colorMap forKey:@"inputGradientImage"];
}

- (void)applyFilterToFrame:(CIImage *)ciFrame {    
    // filter
    [self.colorMapFilter setValue:ciFrame forKey:@"inputImage"];
    CIImage *ciImageResult = [self.colorMapFilter valueForKey: @"outputImage"];

    CGImageRef ref = [self.context createCGImage:ciImageResult fromRect:ciFrame.extent];

    // do whatever you need

    CGImageRelease(ref);
}
于 2015-01-29T09:57:31.300 に答える
3

CIImage をレンダリングする最も速い方法は、EAGLContext にレンダリングすることです。

CI は GPU で動作しますが、CG は CPU レンダラーであるため、CIImage を CGContext にレンダリングすることはそれほど効率的ではありません。CI はその結果を GPU から CPU に読み戻して、CG がレンダリングできるようにする必要があります。

注: このリードバックは、画像が 4K より小さい場合に createCGImage: が呼び出されたときに発生します。画像が大きい場合、CGContextDrawImage が呼び出されたときに発生します。

于 2015-02-01T11:55:02.323 に答える