Mam aplikację WPF na maszynie USG, która wyświetla obrazy ultradźwiękowe generowane w C++ z prędkością do 30 klatek na sekundę.Jak wyświetlić szybko aktualizujące się obrazy bez dużej alokacji pamięci?
Z tego co rozumiem, normalnym procesem wyświetlania obrazów w WPF jest utworzenie BitmapSource dla obrazu i ustawienie źródła dla obrazu, co powoduje jego unieważnienie i wyświetlenie.
Ponieważ BitmapSources nie implementują IDisposable, użycie tej metody zmusiło mnie do utworzenia 30 BitmapSources na sekundę. Dla obrazu 640x480 w formacie 32bppArgb, około 30 MB/s pamięci jest przydzielane na sekundę, a następnie śmieci są ułożone co 10 sekund, powodując widoczne opóźnienie. Oczywiście nie do przyjęcia rozwiązanie.
My obecnie rozwiązaniem jest:
W C++: tworzę System.Drawing.Bitmap (WinForms bitmapę) w Managed C++, zrobić memcpy ze wskaźnikiem do wypełnienia obrazu, użyj Graphics sprzeciw wobec zrobić dodatkowy rysunek, którego potrzebuję, i przekazać go do C#/WPF podczas zdarzenia ImageReceived.
W języku C# Image.Source jest ustawiony do źródła generowanej przez BitmapBuffer, który jest hack sposobem uzyskiwania dostępu do surowych danych o źródle bitmapy: Zobacz this link. Mam P/Invoke z CopyMemory skopiować dane z Bitmap.Scan0 do BitmapBuffer. Następnie unieważniam obraz, aby zaktualizować ekran, i usuwam() obiekt Drawing.Bitmap, aby zwolnić pamięć.
Podczas gdy metoda ta działała przez jakiś czas, wydaje się bardzo hacky i trudno mi uwierzyć, że nie ma innego "odpowiedniego" sposobu, aby to zrobić, niż poprzez refleksję.
Pytanie: Czy istnieje lepszy sposób?
Korzystanie z Marshal.Copy zamiast niebezpiecznego kodu jest jeszcze szybsze i nie wymaga niebezpiecznych bloków. – Andreas