我正在开展一个项目,我们需要捕捉和处理图像以控制机器人。这两件事情都很好。
我似乎能够弄清楚如何使用WPF来显示预处理和后处理图像。
我有一个使用此代码的应用:
public CamNotification(string label1, string label2, BitmapSource image1, BitmapSource image2)
private bool hwLink_SetInfos(CamNotification info)
{
try
{
Application.Current.Dispatcher.BeginInvoke((Action)(() =>
{
lblText1.Content = info.Label1;
lblText2.Content = info.Label2;
ImageBox1.Source = info.Image1;
ImageBox2.Source = info.Image2;
InvalidateVisual();
}));
return true;
}
catch (Exception ex)
{
Debugger.Break();
return false;
}
}
它会更改描述图像的标签和' image.source' s。
它的工作原理 - > fine< - 当我使用WPF按钮来调用代码时,但当我尝试使用Threadpool中的WorkerThread替换两个' image.source&时#39; s即使标签是,也不显示图像。
此外,如果我已按下按钮并显示图片,则来自 - > WorkerThread< - 的调用最终会在MainThread中删除图像并留下空白区域而不是更新他们对新内容。
使用Dispatcher我已经删除了所有的crossthead问题,标签已更新但是" PresentationFramework - > System.Windows.Controls.Image"很清楚,没有更新:-(
在查看stackoverflow时,我发现了这个问题:
似乎关注与我类似的问题。然而,答案和OP都没有评论他如何解决他的问题,这对我有帮助。
我很感激你能给我的任何帮助。
答案 0 :(得分:0)
BitmapImageSource是一个可冻结的对象,如果您打算通过线程访问它,应该将其冻结
来自MSDN
Freezable提供Changed事件以通知观察者任何事件 对对象的修改。冻结Freezable可以改善它 性能,因为它不再需要在变更上花费资源 通知。冻结的Freezable也可以在线程之间共享, 而一个解冻的Freezable则不能。
...
freezable的Freeze方法可让您禁用此自我更新 能力。您可以使用此方法使画笔变为“冻结”或 不可修改的。
当您处理另一个线程上的图像时,您需要更改代码以调用Freeze()
,然后才能在UI线程上使用它。下面的一些工作代码
public CamNotification(string label1, string label2, BitmapSource image1, BitmapSource image2)
private bool hwLink_SetInfos(CamNotification info)
{
try
{
info.Image1.Freeze();
info.Image2.Freeze();
Application.Current.Dispatcher.BeginInvoke((Action)(() =>
{
lblText1.Content = info.Label1;
lblText2.Content = info.Label2;
ImageBox1.Source = info.Image1;
ImageBox2.Source = info.Image2;
InvalidateVisual();
}));
return true;
}
catch (Exception ex)
{
Debugger.Break();
return false;
}
}
一些相关文章:
How do you pass a BitmapImage from a background thread to the UI thread in WPF?
In what scenarios does freezing WPF objects benefit performance greatly?