質問

私は現在、.net 3.5 sp1で導入されたPixelShadersを使用して、画像処理のパフォーマンスを改善する実験を行っています。すべてがはるかに高速ですが、まだwpfフォームの一部の要素にエフェクトが適用されていたので、実際には回避したいです。

多数の画像処理機能があり、パフォーマンスを向上させるために、ピクセルシェーダーを使用して他のものをいくつか置き換えたいと思います。 このようなピクセルシェーダーを表示せずにImageSourceに適用する方法はありますか?

役に立ちましたか?

解決

これが必要な人のために: WPFで行う方法を示すこの記事を作成しました。 http://www.codeproject.com / Articles / 642151 / Pixel-shaders-in-a-background-thread-in-WPF

以下にコピーした関連コード。いくつかの保存された変数を持つクラスからのものです

  • ソース:ImageSource
  • DpiX、DpiY:ソースのDpiを含むdoubles
  • img:WPFイメージコントロール
  • viewbox:WPF ViewBoxコントロール
  • WPF_DPI_X、WPF_DPI_Y:constは値96.0で倍増します

1。画像imgはViewboxに埋め込まれています(画面外でも)

//prepare images
img = new Image();
img.Stretch = Stretch.None;
viewbox = new Viewbox();
viewbox.Stretch = Stretch.None;
viewbox.Child = img; //control to render

2.imgとviewboxは正しい比率に合わせてサイズ調整され、またいくつかのレイアウト関数はviewboxで呼び出されます。これにより、シェーダーが適用された状態でコントロールがレンダリングされます。

/// <summary>
/// Loads the image and viewbox for off-screen rendering.
/// </summary>
public void LoadImage(double width, double height)
{
    img.BeginInit();
    img.Width = width;
    img.Height = height;
    img.Source = Source;
    img.EndInit();

    viewbox.Measure(new Size(img.Width, img.Height));
    viewbox.Arrange(new Rect(0, 0, img.Width, img.Height));
    viewbox.UpdateLayout();
} 

3。そして、画像のコンテンツを取得するには、「スクリーンショット」する場合:

void SaveUsingEncoder(BitmapEncoder encoder, Stream stream)
{
    RenderTargetBitmap bitmap = new RenderTargetBitmap((int)(img.Width * DpiX / WPF_DPI_X), (int)(img.Height * DpiY / WPF_DPI_Y), DpiX, DpiY, PixelFormats.Pbgra32);
    bitmap.Render(viewbox);

    BitmapFrame frame = BitmapFrame.Create(bitmap);
    encoder.Frames.Add(frame);
    encoder.Save(stream);
} 

また、これを別のスレッドで実行する場合は、スレッドを作成する必要があります

thread.SetApartmentState(ApartmentState.STA);

詳細とデモプロジェクトについては、記事を参照してください。

他のヒント

C#の専門家からまだ答えが得られていないのを見て、C ++ DirectX開発者の観点からこれにアプローチしようとします。私の答えが役に立たない場合は、少なくとも正しい方向を指し示すことを望みます。私はC#についてほとんど知らず、PixelShaderがどのようにサポートされるかについても何も知らないため、チャンスは完全に間違っており、ここに書いた内容はまったく当てはまりません。そのような場合は、必要に応じて自由にコメントまたは投票を行ってください

これを実現するためにC ++ / DirectXで一般的に行われることは次のとおりです。

準備(1回実行)

  • CreateRenderTargetを使用してレンダーターゲットを作成
  • CreateOffscreenPlainSurfaceを使用してオフスクリーンサーフェスを作成
  • SetRenderTargetを使用してレンダーターゲットサーフェスを設定する
  • 必要な他の入力リソース(テクスチャ、頂点バッファなど)を作成します

レンダリング(複数回実行)

  • 必要に応じて入力リソース(テクスチャ、バッファ)を更新します
  • レンダリング
  • GetRenderTargetを使用して、レンダーターゲットのコンテンツをオフスクリーンサーフェスにコピーします
  • オフスクリーンサーフェスをロックし、CPUでコンテンツを読み取ります
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top