【发布时间】:2015-06-09 16:04:27
【问题描述】:
我正在尝试使用 WPF 和 MVVM 将相机图像显示到 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 秒很好用,但是在这个延迟之后:我的 Image 变成了白色。在转换器中,image 永远不会是null,因此相机可以正常工作。问题是组件Image 停止重绘。
当Image 为白色时,我可以调整窗口大小或移动它,图像变得很好,因为Image 正在重新绘制。
我做错了什么?
有办法强制Image重绘吗?
为什么Image 停止重绘?
谢谢
EDIT1:
经过一些验证,当图像变为白色时,所有 ui 都会冻结(所以我的按钮在我调整窗口大小或移动窗口之前是不可点击的)
EDIT2
正如评论中的丹尼斯向我建议的那样,我尝试在我的 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");
}
}
在我的Image上直接绑定TestImage
View
<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? -
完整类型为
System.Drawing.Bitmap。我试试看 -
这正在慢慢变成一个调试会话。 Stack Overflow 上的帖子应该包含一个问题(不帮助我调试),并且随着时间的推移不会发生太大变化。也许您可以通过聊天获得帮助:chat.stackoverflow.com 并在解决问题后解决问题。