使用WPF和MVVM,我正在尝试将相机图像显示到
每帧,我更新变量_bmpImage:
视图模型
为了将
最终将其绑定到我的视图中:
15秒内一切正常,但之后我的图片变成了白色。在转换器中,图片从未为 null,所以相机工作正常。问题是组件 Image 停止重绘。当图片变成白色时,我可以调整窗口大小或移动窗口,这样图片就会恢复正常,因为 Image 会重新绘制。
我做错了什么吗?有办法强制 Image 重新绘制吗?为什么 Image 停止重绘?
谢谢
编辑1:经过一些检查,当图片变成白色时,所有用户界面都会冻结(因此在我调整窗口大小或移动窗口之前无法单击按钮)。
编辑2:正如评论中的 Dennis 建议,我尝试在 ViewModel 中进行转换:为此,我添加了一个代表已转换图像的属性:
Image
中。
每次相机获取一帧图像时都会调用回调函数:
视图模型
public void OnNewFrame(object sender, EventArgs e)
{
Camera camera = sender as MyCamera;
camera.ToBitmap(out _bmpImage);
RaisePropertyChanged("BMPImage");
}
每帧,我更新变量_bmpImage:
视图模型
private Bitmap _bmpImage;
public Bitmap BMPImage
{
get
{ return _bmpImage; }
private set
{ _bmpImage = value; RaisePropertyChanged("BMPImage"); }
}
为了将
Bitmap
转换为BitmapImage
,我使用了一个转换器:
转换器
public class ImageToSource : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
Image image = value as Image;
if (image != null)
{
MemoryStream ms = new MemoryStream();
image.Save(ms, ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
return bi;
}
return null;
}
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
最终将其绑定到我的视图中:
<Image Source="{Binding Main.BMPImage, Converter={StaticResource ImageToSource}}"></Image>
15秒内一切正常,但之后我的图片变成了白色。在转换器中,图片从未为 null,所以相机工作正常。问题是组件 Image 停止重绘。当图片变成白色时,我可以调整窗口大小或移动窗口,这样图片就会恢复正常,因为 Image 会重新绘制。
我做错了什么吗?有办法强制 Image 重新绘制吗?为什么 Image 停止重绘?
谢谢
编辑1:经过一些检查,当图片变成白色时,所有用户界面都会冻结(因此在我调整窗口大小或移动窗口之前无法单击按钮)。
编辑2:正如评论中的 Dennis 建议,我尝试在 ViewModel 中进行转换:为此,我添加了一个代表已转换图像的属性:
private BitmapImage _testImage;
public BitmapImage TestImage
{
get
{ return _testImage; }
private set
{ _testImage = value; RaisePropertyChanged("TestImage"); }
}
我直接将_bmpImage
转换为OnNewFrame
:
public void OnNewFrame(object sender, EventArgs e)
{
Camera camera = sender as MyCamera;
camera.ToBitmap(out _bmpImage);
//RaisePropertyChanged("BMPImage");
if (_bmpImage != null)
{
// Convertion
MemoryStream ms = new MemoryStream();
_bmpImage.Save(ms, ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
_testImage = new BitmapImage();
_testImage.BeginInit();
_testImage.StreamSource = ms;
_testImage.EndInit();
RaisePropertyChanged("TestImage");
}
}
并且直接将TestImage
绑定到我的Image
视图
<Image Source="{Binding Main.TestImage}" />
使用此代码时,我遇到了异常:
Must create DependencySource on same Thread as the DependencyObject
编辑 3
我考虑了你的意见,这是我的新代码:
if (_bmpImage != null)
{
// Convertion
Console.WriteLine("ok");
MemoryStream ms = new MemoryStream();
_bmpImage.Save(ms, ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
_testImage = new BitmapImage();
_testImage.BeginInit();
_testImage.StreamSource = ms;
_testImage.EndInit();
ms.Dispose();
System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)(() =>
{
RaisePropertyChanged("TestImage");
}));
}
在RaisePropertyChanged("TestImage")
处,我遇到了相同的异常。
请注意Edit2和Edit3只是测试,并没有回答我最初的问题。
对于篇幅过长,我深感抱歉。
Bitmap
的完整类型名称是什么?您是否尝试在视图模型中执行转换,并从VM公开ImageSource
属性而不是Bitmap
? - DennisSystem.Drawing.Bitmap
。我来试一下。 - Titouan56