Frage

Ich experimentiere derzeit Pixelshader eingeführt mit .net 3.5 SP1 unter Verwendung von Bildverarbeitungsleistung zu verbessern. alles ist viel schneller, aber bis noch ich gerade hatte Auswirkungen in meinem Wpf Formen auf einige Elemente angelegt, dass ich möchte eigentlich vermeiden.

Wir haben eine Reihe von Bildverarbeitungsfunktionalität und ich möchte einige othe das Material Stück für Stück mit Pixel-Shader ersetzen einige Performance zu gewinnen. ist es eine Möglichkeit, einen solchen Pixel-Shader zu einem Image anzuwenden, ohne dass es angezeigt wird?

War es hilfreich?

Lösung

Für die muss noch dies: Ich habe gerade in diesem Artikel hier, die zeigt, wie es in WPF zu tun. http://www.codeproject.com / Artikel / 642.151 / Pixel-Shadern-in-a-Hintergrund-Thread-in-WPF

Der entsprechende Code unten kopiert. es ist aus einer Klasse mit einigen gespeicherten Variablen

  • Quelle: ein Imagesource
  • DpiX, DpiY: Doppel Dpi der Quelle mit
  • img: WPF Bildsteuerung
  • Sichtbox: WPF ViewBox Kontrolle
  • WPF_DPI_X, WPF_DPI_Y: const verdoppelt mit dem Wert 96,0

1.den Bild img in einer Viewbox eingebettet (auch Off-Screen)

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

2.img und Sichtbox ist so bemessen, um die richtigen Proportionen, auch einige Layout-Funktionen auf Sichtgerät aufgerufen werden. diese machen die Kontrollen mit dem Shader angewendet machen.

/// <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.Und den Inhalt des Bildes zu erhalten, ein „Screenshot“, wenn man so will:

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);
} 

Auch wenn Sie diese in einem separaten Thread ausführen möchten, müssen Sie einen Thread mit

erstellen
thread.SetApartmentState(ApartmentState.STA);

für weitere Informationen und ein Demo-Projekt finden Sie im Artikel.

Andere Tipps

Sehen Sie keine Antwort noch aus C # Experten erhalten haben, werde ich versuchen, diese aus Sicht C ++ DirectX Entwickler zu nähern, in der Hoffnung, dass, wenn meine Antwort nicht nützlich ist, zumindest es Sie in die richtige Richtung zeigen wird. Ich weiß wenig über C # und nichts darüber, wie Pixelshader unterstützt werden, daher ist Chance Uhr komplett falsch und was schreibe ich hier gar nicht gelten. In einem solchen Fall fühlen Sie sich frei oder nach unten Abstimmung Kommentar nach Bedarf

Was im Allgemeinen in C ++ / DirectX geschieht dies achive ist:

Vorbereitung (done einmal)

  • Erstellen Renderziel mit CreateRenderTarget
  • Erstellen Off-Screen-Oberfläche mit CreateOffscreenPlainSurface
  • Stellen Sie Zieloberfläche machen mit SetRenderTarget
  • Erstellen Sie alle anderen Eingangs benötigten Ressourcen (Texturen, Vertex Buffer ...)

Rendering (done mehrfach)

  • Aktualisieren Eingang Ressourcen (Texturen, Puffer) nach Bedarf
  • Render
  • Kopieren Sie den Inhalt des Renderziel in die Off-Screen-Oberfläche über GetRenderTarget
  • Sperren Sie die Off-Screen-Oberfläche und lesen Sie dessen Inhalt auf der CPU
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top