質問:
WritableBitmap
から提供されたビットマップを UI に表示するためにスケーリングおよび/またはトリミングする高速な方法は何ですか?
要件:
- CPU 使用率が低い
- 大きな画像の処理 (5 メガピクセル、約 2500x2000 ピクセル)
- ビットマップが表示される UI 要素と同じ解像度/領域にサイズ変更および/またはトリミングします。
- WPF を使用する
具体的には、14FPS の 5 メガピクセルのカメラ イメージ ストリームを WPF UI 要素にフル スピードで表示できるようにする必要があります。
アップデート:
次のようにをCanvas
使用してコントロールにペイントすることで、描画をかなり高速化できました。ImageBrush
m_bitmap
WriteableBitmap
ImageBrush brush = new ImageBrush();
brush.ImageSource = m_bitmap;
brush.Stretch = Stretch.Uniform;
canvas.Background = brush;
まだ約 20% の CPU を使用していますが、完全な 14 FPS を取得できるようになりました。そのため、カメラを 1 つまたは 2 つ追加した場合 (4 つほどを実行する予定です)、どのように機能するかはわかりません。
描画が遅くなる可能性があると私が思うもう1つのことは、画像が標準のRGB32(またはWPFのbgra32ですか?)形式ではなく、モノクロのGray8形式であることです。私の理解が正しければ、画像を標準形式に変換して表示する必要があります。これにより、各フレームの描画時間に大きなオーバーヘッドが追加されます。
背景:
現在、5 メガピクセル、14 FPS のビデオ カメラを使用しており、フレームをフル スピードで画面にレンダリングしようとしています。これをWPFで実現したいと考えています。
現在、スケーリングされていない画像に対してフルスピードで実行される WinForms の例がありますが、(予想どおり) pictureBox.SizeMode = Zoom;
. この例では、生データをカメラ ストリームからバッファーに直接読み取り、そのデータをバッファーからPictureBox
コントロールに設定されたビットマップにコピーします。コピー アルゴリズムは、LockBits を使用して処理を高速化します。
その例を WPF に変換し、オブジェクトを使用してパーツを書き直して、代わりにオブジェクトとコントロールをBitmap
使用するようにしました。残念ながら、これは適切な速度で、スケーリングされているかどうかに関係なく、ストリームを画面にレンダリングできません。どちらも CPU 負荷が高く、更新が非常に遅いです。WritableBitmap
Image
PictureBox
画面へのレンダリングがオフになっているときのパフォーマンスは素晴らしいです。約 3% の CPU と 100MB 未満のメモリを使用しながら、フル スピードと解像度で画像ストリームを処理できます。
注: 画面へのレンダリングがオフになっていると言うと、WritableBitmap はまだ継続的に更新されており、Image コントロールに設定されていません。
私は、WPF でビットマップを高速に更新することについて多くの議論を見てきましたが、適切な速度/CPU 負荷で動作させることに成功していません。また、画像全体が見えるように画像を拡大縮小したいと思います。
キーは、WPFが500万ピクセルすべてをレンダリング(キャッシュ?)しようとせず、画面上のピクセルのみ、現在の画面解像度でのみレンダリング(キャッシュ)しようとする必要がある、ある種のスケーリング/クロップの組み合わせにあると思います. これはかなり簡単に、メモリや CPU にあまり負担をかけることなく実行できると思いますが、現在のところ、その方法がわかりません。DecodePixelWidth
とのプロパティを見つけましたDecodePixelHeight
が、これらはファイルからBitmapImage
.