3

WPF アプリケーションで画像を処理したいと考えています。ただし、実行時にメモリ内の BitmapSource のピクセルを変更したいと思います。

私は現在、昔ながらの System.Drawing.Bitmap に対して「安全でない」コードを使用してこれを行うことに成功しています。このアプローチは、次の投稿で説明されています

これを WPF で機能させるために、次のアプローチを使用して WPF BitmapSource を作成しています。

    BitmapSource destination;
    IntPtr hBitmap = bitmap.GetHbitmap();
    BitmapSizeOptions sizeOptions = BitmapSizeOptions.FromEmptyOptions();
    destination = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, sizeOptions);
    destination.Freeze();
    return destination;

ただし、これによりメモリ内に多くのコピーが作成されるため、EricGu がビットマップの例で示したように、そこにアクセスして BitmapSource 内の基になるビットをいじりたいと思っています。これは可能ですか?

PixelShaders はおそらくこれを行うことができると認識していますが、これは複数のスレッドを含む学術的な演習です (これは、ビットマップをアンセーフ モードで編集するときにサポートされます)。

前もって感謝します

4

1 に答える 1

3

私が知っている限りのことをお話しします。

まず、ビットマップをメインスレッドに戻す前に、ビットマップのフリーズについてすでに知っているようです。それは良いスタートです。

BitmapSource から新しい実装を派生させてコピーを減らし、ビットマップからデータをコピーする仮想関数をオーバーライドしようとしたことがあります。機能しましたが、大量のメモリ リークが発生しました。それを理解したことがありません。

もちろん、バイト配列から BitmapSource を直接作成することもできます (GDI ビットマップのオーバーヘッドが失われます)。msdn ドキュメント

WriteableBitmapを検討しましたか? これが、すべてのコピーに関する共通の不満に対する WPF チームの対応でした。

編集:MSDNは、バックグラウンドスレッドから使​​用できることを明示的に(WritableBitmap.BackBufferドキュメントで)述べています:

処理のために BackBuffer ポインターを外部コンポーネントや他のスレッドに渡すことができますが、そうする場合は、独自のスレッド調整を提供する必要があります。特に、UI スレッドが AddDirtyRect メソッドを呼び出して変更された領域を指定し、UI スレッドが Unlock メソッドを呼び出してバッファーのロックを解除するようにする必要があります。

したがって、UI スレッドにロックとポインターを取得させると、ワーカー スレッドにピクセルを書き込むことができます。

于 2010-10-13T13:10:05.787 に答える