Question

Je teste actuellement l'utilisation de PixelShaders introduite avec .net 3.5 sp1 pour améliorer les performances de traitement des images. tout est beaucoup plus rapide, mais jusqu'à présent, des effets ont été appliqués à certains éléments de mes formes wpf, ce que je veux réellement éviter.

nous avons un tas de fonctionnalités de traitement d’images et je souhaiterais en remplacer certaines pièces par des pixel shaders pour gagner en performance. y a-t-il un moyen d'appliquer un tel pixel shader à un ImageSource sans avoir à l'afficher?

Était-ce utile?

La solution

Pour ceux qui en ont encore besoin: Je viens de créer cet article ici qui montre comment le faire dans WPF. http://www.codeproject.com / Articles / 642151 / Pixel-shaders-in-a-background-thread-in-WPF

Le code pertinent copié ci-dessous. c'est d'une classe avec des variables stockées

  • Source: une source d’image
  • DpiX, DpiY: les doubles contenant Dpi de source
  • img: contrôle d'image WPF
  • viewbox: contrôle WPF ViewBox
  • WPF_DPI_X, WPF_DPI_Y: const double avec la valeur 96.0

1. L’image img est intégrée dans une boîte de visualisation (également hors écran)

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

2.img et viewbox sont dimensionnés aux proportions correctes. Certaines fonctions de présentation sont également appelées sur viewbox. Cela rend les contrôles avec le shader appliqué.

/// <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.Et pour obtenir le contenu de l'image, une "capture d'écran". si vous voulez:

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

En outre, si vous souhaitez l'exécuter dans un thread séparé, vous devez créer un thread avec

.
thread.SetApartmentState(ApartmentState.STA);

pour plus d'informations et un projet de démonstration, voir l'article.

Autres conseils

Voyant que vous n’avez pas encore obtenu de réponse de la part des experts en C #, je vais essayer d’aborder ceci du point de vue des développeurs C ++ DirectX, en espérant que si ma réponse n’est pas utile, elle vous indiquera au moins une direction à suivre. Je connais peu de choses sur C # et rien sur la manière dont PixelShaders est pris en charge. Par conséquent, la chance est que je suis complètement faux et ce que j'écris ici ne s'applique pas du tout. Dans ce cas, n'hésitez pas à commenter ou à voter pour au besoin

Ce qui est généralement fait dans C ++ / DirectX pour y parvenir est:

Préparation (effectuée une fois)

  • Créer une cible de rendu à l'aide de CreateRenderTarget
  • Créer une surface hors écran à l'aide de CreateOffscreenPlainSurface
  • Définissez la surface cible du rendu à l'aide de SetRenderTarget
  • Créez d'autres ressources d'entrée nécessaires (textures, tampons de sommets, etc.)

Rendu (effectué plusieurs fois)

  • Mettez à jour les ressources d'entrée (textures, tampons) selon vos besoins
  • Rendu
  • Copiez le contenu de la cible de rendu dans la surface hors écran via GetRenderTarget
  • Verrouillez la surface hors écran et lisez son contenu sur la CPU
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top