【发布时间】:2019-09-18 15:31:49
【问题描述】:
我有一个连接到网络摄像头的 c++ dll。我正在尝试将这些帧调用到 c# wpf 应用程序中进行显示。
我有一个在 dll 中运行并通过回调将数据发回的线程,如下所示:Updated 函数在每个新帧被调用,并更新 zedframe 数据;
// class A
//callback from a c++ dll.
public IntPtr zedFrame;
public Mutex mutex = new Mutex();
public bool bGotFrame = false;
public event EventHandler Updated;
protected virtual void Updated(EventArgs e, IntPtr frame)
{
mutex.WaitOne(); // Wait until it is safe to enter.
zedFrame = frame;
mutex.ReleaseMutex(); // Release the Mutex.
bGotFrame = true;
}
在同一个类中,我有这个函数“应该”以线程安全的方式获取帧数据。
public IntPtr getFrame()
{
IntPtr tmp;
mutex.WaitOne(); // Wait until it is safe to enter.
tmp = zedFrame;
mutex.ReleaseMutex(); // Release the Mutex.
return tmp;
}
在 wpf 表单中,我有一张图片:
<Grid>
<Image Name="ImageCameraFrame" Margin="5,5,5,5" MouseDown="GetImageCoordsAt"/>
</Grid>
在表单的cs中,我有一个DispatcherTimer
//以图像形式.xaml.cs
var timer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(100)
};
timer.Tick += Timer_Tick;
private void Timer_Tick(object sender, EventArgs e)
{
if (ClassA.bGotFrame == true)
{
var data = ClassA.getFrame();
var width = 1280;
var height = 720;
var stride = 3 * width;
var bitmap = BitmapSource.Create(width, height, 96, 96,
PixelFormats.Rgb24, null, data, stride * height, stride);
bitmap.Freeze();
ImageCameraFrame.Source = bitmap;
}
}
当我运行它时,它会连接,显示一个帧,然后使应用程序崩溃。 我正在冻结位图,并使用互斥锁。 我做错了什么?
是否可以将图像源绑定到另一个类中的变量,在另一个线程中更新?还是我需要计时器?
【问题讨论】:
-
您可以使用简单的
lock(){},而不是处理互斥锁。冻结意味着它现在是线程安全的,回调在哪个线程上,是 UI 还是后台? -
后台回调。
-
可能是计时器在每个图像帧中不止一次滴答作响,并且在同一帧中将
ClassA.bGotFrame视为true- 然后尝试使用相同的内存图像制作两个或更多图像?也许尝试设置bGotFrame = false;ingetFrame()? -
我还建议不要为每一帧创建一个新的 BitmapSource。相反,将单个 WriteableBitmap 分配给 Image 的 Source 属性,然后重复更新其 BackBuffer 属性:stackoverflow.com/a/12587470/1136211