2009-08-30 3 views
1

私は、OpenGLを使用せずにUIImageのRGBA値を変更するためにピクセルの繰り返しを実行しようとしています。私は、以下のコードを使用して反復パフォーマンスをテストしようとしましたが、非常に不快でした。私は毎秒数千回しか反復することができないようでした。そして、数十万ピクセルのUIImageの場合、これは長すぎるでしょう...誰かがパフォーマンスを向上させる方法や、これらのような操作に通常どのくらいの時間を要するかについての提案はありますか?Core GraphicsのiPhoneでのPIXELの繰り返しパフォーマンスが悪いですか?

-(UIImage*)modifyPixels:(UIImage*)originalImage 
{ 
    NSData* pixelData = (NSData*)CGDataProviderCopyData(CGImageGetDataProvider(originalImage.CGImage)); 
    void* pixelBytes = [pixelData bytes]; 

    // Take away the red pixel, assuming 32-bit RGBA 
    for(int i = 0; i < [pixelData length]; i += 4) { 
     NSLog(@" %ith iteration (%i/%i/%i/%i)", i, pixelData[i], pixelData[i+1], pixelData[i+2], pixelData[i+3]); 
    } 

    //NSData* newPixelData = [NSData dataWithBytes:pixelBytes length:[pixelData length]]; 
    //UIImage* newImage = [UIImage imageWithData:newPixelData]; 

    return originalImage;  
} 
+0

ここでは、pixelDataが漏洩していることに注意してください。 "Copy"を含むCore Foundation(およびCG拡張機能)関数は、保持されたオブジェクトを返します。 –

+0

よろしくお願いいたします。 – RexOnRoids

答えて

4

NSLogステートメントはイメージの反復処理をかなり遅くします。良いテストは、ピクセルデータをログアウトする代わりにイメージを反転させることです。また、各反復のデータ長を計算することも遅くなります。長さをローカル変数にキャッシュし、代わりにそれを使用します。

+0

合意。 NSLog()は非常に遅くなる可能性があります。 –

+0

ありがとうございます。それはたくさんの助けになりました! – RexOnRoids

5

[pixelData length]をループ内で呼び出さないでください。コンパイラはこのメッセージの結果が一定であることを知ることができないので、代わりにメソッドを呼び出します。

+0

これはとても良いヒントです。私は経験豊富な開発者でさえこれを見落とすことを見た。 – rpetrich

0

コードの基本的な問題は、ピクセルを4バイトの要素として扱うことです。最初のステップとして実行する必要があるのは、4バイトのブロックを1ワードとして読み取ることです。 uint32_t型を使用し、一度に1ワードずつレジスタに読み込みます。その結果、メモリ読み出し動作が4倍少なくなり、各ピクセルは1 32ビットレジスタに格納されます。各ワードにはRGBAが含まれ、各コンポーネントは32ビットワードの8ビットを占めます。次に、ビットシフト操作を使用してコンポーネントを操作する必要があります。ここでは、iOSのネイティブBGRA形式のピクセルpixel_binary_layoutでそれを行う方法を示すブログ記事があります。ピクセルロジックが何であれ、結果を書き出し、その結果をチェックして、すべてが期待どおりに機能していることを確認する必要があります。 ARMチップにワード全体を読み書きする方法は、バイト読み込み回数を4倍にするよりも速いので、大きな改善が見られるはずです。