2009-04-30 20 views
7

私は、パンすることができるタイルグラフィックを表示するWPFコントロール(FrameworkElementから継承)を作成しました。各タイルは24bppで256x256ピクセルです。私はOnRenderをオーバーライドしました。そこに、新しいタイル(BitmapFrameとして)をロードし、次に、すべての可視タイルをdrawingContext.DrawImageを使用して描画します。BitmapSourceでのWPFレンダリング

レンダリングサイクルごとに1つ以上の新しいタイルがあると、フレームレートは60秒から0秒に約1秒間低下します。これは、画像の読み込み(ミリ秒単位)やDrawImage(中間レンダリングデータ構造を単に埋めるため、時間がかかりません)によって引き起こされるものではありません。

私は、レンダスレッド自体が新しいBitmapSourceインスタンス(つまり、まだキャッシュされていなかったもの)が大量(〜20)になるたびにチョークすると思います。いずれかの内部DirectX互換の形式に変換するのに多くの時間を費やすか、キャッシュの問題である可能性があります。ビデオRAMを使い果たすことはできません。パーフォレータは60MB以下でピークを示し、私は256MBを持っています。また、Perforatorは、すべてのレンダリングターゲットがハードウェアアクセラレーションであると言います。

洞察力があれば幸いです!事前

ダニエル

おかげ

@RandomEngy:
BitmapScalingMode.LowQuality問題を少し減少したが、それを取り除くしませんでした。私はすでに意図した解像度でタイルをロードしています。また、それは最新のグラフィックドライバではありません(Nvidia)。
スケーリングにはそれほど時間がかかることに少し驚いています。私がそれを理解している方法では、ビットマップ(サイズに関係なく)はDirect3Dテクスチャとして読み込まれ、その後ハードウェアスケールされます。実際、ビットマップが初めてレンダリングされると、それ以上のフリーズをせずに回転とスケールを変更できます。

答えて

3

大量の画像だけではありません。 1つの大きなイメージでは、イメージが読み込まれるまでレンダリングを停止するのに十分です。イメージのサイズが数千に上がり始めると、かなり目立ちます。

おそらくレンダリングスレッドだと私は同意します:テストを行いましたが、このレンダリング遅延が完全にプリキャッシュされたBitmapImageを表示しようとしている間にUIスレッドがメッセージをうまくディスパッチしていました。

あなたが推測していたように、イメージ上で何らかの変換や準備をしているに違いありません。私は "レンダリング"してイメージを隠し、それを表示する必要があるときにそれを明らかにすることで、私のアプリでこれを軽減しようとしました。しかし、レンダリングのフリーズはとにかく起こるため、これは理想的ではありません。

は、(編集)

いくつかのフォロー:MS WPFエイリアスの議論の後、私は遅延を引き起こしていたものを見つけました。私のServer 2008マシンでは、新しいWDDMドライバモデルをサポートしていない古いビデオドライバと、イメージのサイズを変更するための遅延が組み合わされていました。

ソースイメージのサイズが表示サイズと異なる場合、イメージが表示される前にレンダリングスレッドが遅延します。デフォルトでは画像は最高品質に設定されていますが、レンダリングのスケーリングオプションはRenderOptions.SetBitmapScalingMode(uiImage, BitmapScalingMode.LowQuality);に変更することができます。私がそれをしたら、イメージを表示する前に不思議な凍結がなくなりました。別の方法として、スケーリングの品質低下が気に入らなければ、DecodePixelWidth/Heightを表示するサイズに等しいBitmapImageを読み込むことです。 BitmapImageをバックグラウンドスレッドにロードすると、表示に時間がかかることはありません。

0

また、これらを試してください。

/* ivis is declared in XAML <Image x:Name="iVis" UseLayoutRounding="True" SnapsToDevicePixels="True" /> */ 

iVis.Stretch = Stretch.None; 
RenderOptions.SetBitmapScalingMode(iVis, BitmapScalingMode.NearestNeighbor); 
RenderOptions.SetEdgeMode(iVis, EdgeMode.Aliased); 
VisualBitmapScalingMode = BitmapScalingMode.NearestNeighbor; 
iVis.Source = **** your bitmap source **** 

「A」チャンネルの色の膨大な量を使用したとき、私はイメージが、それは私のためにはるかに良い仕事を拡張するために、レンダリングした後まで待って、パフォーマンスといくつかの問題を抱えていました。

また、タイル貼りのグラフィックを使用しているとお伝えしましたか?

通常、FrameworkElementにブラシとして設定するには、TileBrushを使用します。それらをアニメートしたり、新しいものを動的に追加したりする場合は、ブラシを生成して手動でオブジェクトに適用することもできます。できるだけフリーズしてください。また、VisualBitmapScalingModeは任意のVisualのプロパティです。

関連する問題