Est-il possible de modifier une BitmapSource WPF en mémoire « unsafe'ly d'un autre fil
-
29-09-2019 - |
Question
Je voudrais faire un peu de traitement d'images dans une application WPF. Cependant, je souhaite modifier les pixels d'une BitmapSource en mémoire lors de l'exécution.
Je gère actuellement le faire en utilisant le code « dangereux » contre une ancienne System.Drawing.Bitmap et il fonctionne un régal (verrouiller une zone de travail, jouer avec les pixels) travail. L'approche est décrite dans cet article: http://blogs.msdn.com/b/ericgu/archive/2007/06/20/lost-column-2-unsafe-image-processing.aspx
Pour obtenir ce travail dans WPF Je crée alors un BitmapSource WPF en utilisant cette approche:
BitmapSource destination;
IntPtr hBitmap = bitmap.GetHbitmap();
BitmapSizeOptions sizeOptions = BitmapSizeOptions.FromEmptyOptions();
destination = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, sizeOptions);
destination.Freeze();
return destination;
Cependant, cela crée beaucoup de copies en mémoire et je veux vraiment obtenir là-bas et jouer avec les bits sous-jacents à l'intérieur du BitmapSource comme EricGu dans l'exemple montré Bitmap. Est-ce possible?
Je me rends compte que pixelShaders peut probablement faire cela, mais c'est un exercice académique impliquant plusieurs threads (qui est pris en charge lors de l'édition d'un bitmap en mode non sécurisé).
Merci à l'avance
La solution
Je vais vous dire autant que je sache.
D'abord, vous semble déjà savoir au sujet bitmaps congélation avant de les remettre au thread principal. C'est un bon début.
J'ai essayé une fois de réduire la copie en dérivant une nouvelle implémentation de BitmapSource et passer outre les fonctions virtuelles qui copient vos données du bitmap. Il a travaillé, mais a produit des fuites de mémoire massives. Jamais compris.
Vous pouvez aussi créer un cours BitmapSource directement à partir d'un tableau d'octets (et les frais généraux lose du bitmap GDI). msdn docs
Avez-vous considéré comme un WriteableBitmap ? Ce fut la réponse de l'équipe WPF à la plainte commune au sujet de toutes les copies.
Modifier : MSDN dit explicitement (dans la documentation WritableBitmap.BackBuffer) qu'il peut être utilisé à partir d'un fil de fond:
Vous pouvez passer le pointeur backbuffer à des composants externes et d'autres fils pour le traitement, mais si vous le faites, vous doit vous fournir propre fil coordination. vous devez, en particulier, veiller à ce que précise le thread d'interface utilisateur zones modifiées en appelant la Procédé AddDirtyRect, et en ce que l'interface utilisateur fil libère le tampon en appelant la méthode de déverrouillage.
Donc, si vous laissez le thread d'interface utilisateur Aquire la serrure et le pointeur, vous pouvez laisser un thread de travail écrire les pixels.