Я знаю, что оригинальному сообщению уже более 3 лет, но я просто пытался выяснить, как использовать этот код. Я обнаружил, что ответ, данный Дими, является почти полностью функциональным кодом. Однако я обнаружил, что у меня есть проблемы с утечкой памяти и ненадежным отображением кадра на некоторых компьютерах. Код отлично работал на моем более совершенном компьютере для разработки (i7, 16 ГБ ОЗУ, карта Quadro Pro Grapthics), но когда я развернул приложение на компьютере с более ограниченными ресурсами (i5, 4 ГБ ОЗУ, интегрированная графика Intel), рамка исчезает один раз в некоторое время, и программа также будет аварийно завершать работу после исчерпания системной памяти. Пройдя некоторое время в интернете, я думаю, что наконец-то собрал воедино рабочий код, основанный на всех отзывах людей. Я знаю, что другой компьютер способен выполнять захват кадров с веб-камеры, потому что у меня есть приложение WinForm C #, которое я написал с помощью AForge.NET, и у него нет проблем с надежным рендерингом кадров без утечки памяти. К сожалению, WPF не обрабатывает графику так же, как WinForm, и мы должны сделать это, чтобы заставить AForge.NET работать с ним.
По сути, код такой же, как у Дими, за исключением метода Cam_NewFrame.
void Cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
try
{
BitmapImage bi;
using(var bitmap = (Bitmap)eventArgs.Frame.Clone())
{
bi = new BitmapImage();
bi.BeginInit();
MemoryStream ms = new MemoryStream();
bitmap.Save(ms, ImageFormat.Bmp);
bi.StreamSource = ms;
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.EndInit();
}
bi.Freeze();
Dispatcher.BeginInvoke(new ThreadStart(delegate { frameHolder.Source = bi; }));
}
catch (Exception ex)
{
//catch your error here
}
}
Были внесены следующие изменения:
- Включение обработки растрового изображения с использованием области видимости, так что любая неиспользуемая память очищается сразу после окончания области действия.
- Перемещение bi.BeginInit () перед обработкой потока памяти, чтобы растровое изображение было сразу готово для дампа памяти.
- Изменение CacheOption на OnLoad, чтобы вся память изображений была выгружена прямо при загрузке. В противном случае он использует BitmapCacheOption.Default, который может позволить изображению удерживаться в памяти, даже когда выдается bi.Freeze (). Это привело к тому, что кадр не отображался даже при вызове Dispatcher.BeginInvoke для визуализации изображения.
Пока что все работает хорошо, но если кто-то еще заметит другие проблемы, пожалуйста, оставьте комментарий, чтобы мы знали, как это исправить.