1

CGImage から画像を描画するアプリケーションがあります。

CImage 自体は、CGImageSourceCreateImageAtIndex を使用して読み込まれ、PNG ファイルから画像が作成されます。

これはスプライト エンジンの一部を形成します。1 つの PNG ファイルに複数のスプライト イメージがあるため、各スプライトには CGImage のどこにあるかを定義する CGRect があります。

問題は、CGContextDraw が目的の四角形のみを取り、ソースの CGImage を引き伸ばして塗りつぶすことです。

したがって、各スプライト イメージを描画するには、CGImageCreateWithImageInRect() を使用して、元のソースから複数の CGImage を作成する必要があります。

最初は、これは「安上がりな」操作だと思っていました。各 CGImage にイメージ ビットの独自のコピーを含める必要はないように思われます。

CGImage のサブセクションを CGContext に描画するためのより最適な方法があるので、CGImageCreateWithImageInRect() を頻繁に使用する必要はありませんか?


ソースの四角形がなく、CGImage 上の四角形から CGImage を簡単に作成できることを考えると、おそらく CGImage は、CGImage から作成された CGImage がサブ四角形を参照するコピーオンライト セマンティックを実装しているのではないかと疑い始めました。親と同じ物理ビットの。プロファイリングはこれが間違っていることを証明しているようです:/

4

4 に答える 4

2

私はあなたと同じ船に乗っていました。CGImageCreateWithImageInRect()私のニーズにはうまくいきましたが、以前は に変換しようとしましたがNSImage、その前に、描画しているコンテキストをクリッピングCGContextDrawImage()し、クリッピングされた領域に正しいデータを描画するように変換していました。

私が試したすべての解決策のうち:

  1. クリッピングと変換は、CPU に非常に負担をかけていました。遅すぎました。ビットマップ データの量を増やしても、パフォーマンスに大きな影響を与えるのはごくわずかであり、このアプローチにはスケーラビリティが欠けていることが示唆されました。

  2. への変換NSImageは、少なくとも使用していたデータについては比較的効率的でした。私が見ることができたビットマップ データの重複はないように見えました。

  3. ある時点CIImageで、このクラスは画像の部分領域の描画も許可するため、 に変換しました。これは への変換よりも遅いように見えましたがNSImage、いくつかのコア イメージ フィルターを通過することで、ビットマップをいじる機会が得られました。

  4. 使用CGImageCreateWithImageInRect()は最も高速でした。これは、最後に使用してから最適化されている可能性があります。この関数のドキュメントには、結果のイメージが元のイメージへの参照を保持していると書かれています。これは、コピー オン ライト セマンティクスに関して想定していたことと一致しているようです。私のベンチマークでは、データの重複はないように見えますが、結果を間違って読んでいる可能性があります。私たちがこの方法を採用したのは、それが最速であるだけでなく、プロセス全体を 1 つのフレームワークに保持する、より「クリーンな」アプローチのように思えたからです。

于 2012-12-04T01:29:37.137 に答える
0

CGImage で NSImage を作成しますNSImage オブジェクトを使用すると、その一部のセクションのみを目的の四角形に簡単に描画できます。

于 2010-08-25T14:10:10.923 に答える
0

クリッピング領域を使用することをお勧めします。

于 2010-08-25T17:14:26.850 に答える