EmguCV:在 PropertyChanged 事件之后,BitmapSource 未在 GUI 上更新:
EmguCV: BitmapSource isn't updated on GUI after PropertyChanged Event:
我只想捕捉并在我的视图中显示相机图片,每秒更新一次。但是,绑定到我的 Bitmapsource CurrentFrame
的图像容器在运行时保持空白。
到目前为止,这是我的代码(主要采用 an answer of another thread with similar topic:
public class CameraViewModel : ViewModelBase
{
public CameraViewModel()
{
StartVideo();
}
private DispatcherTimer Timer { get; set; }
private VideoCapture Capture { get; set; }
private BitmapSource currentFrame;
public BitmapSource CurrentFrame
{
get { return currentFrame; }
set
{
if (currentFrame != value)
{
currentFrame = value;
SetProperty(ref currentFrame, value);
}
}
}
private void StartVideo()
{
//CurrentFrame = new BitmapImage(new Uri("C:\Users\Johannes\Pictures\Camera Roll\asdf.bmp")) as BitmapSource;
Capture = new VideoCapture();
Timer = new DispatcherTimer();
//framerate of 10fps
Timer.Interval = TimeSpan.FromMilliseconds(1000);
Timer.Tick += new EventHandler(async (object s, EventArgs a) =>
{
//draw the image obtained from camera
using (Image<Bgr, byte> frame = Capture.QueryFrame().ToImage<Bgr, byte>())
{
if (frame != null)
{
CurrentFrame = ToBitmapSource(frame);
}
}
});
Timer.Start();
}
public static BitmapSource ToBitmapSource(IImage image)
{
using (System.Drawing.Bitmap source = image.Bitmap)
{
IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap
BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ptr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
DeleteObject(ptr); //release the HBitmap
return bs;
}
}
/// <summary>
/// Delete a GDI object
/// </summary>
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
}
一些为了更好理解的事情:
- ViewModelBase class 合并并处理
INotifyPropertyChange 事件。
- 数据绑定正在运行!我测试过
它,通过将 bmp 文件分配给
CurrentFrame
StartVideo()
方法 - 图像在运行时显示在 GUI 中。
SetProperty()
方法按预期每 1000 毫秒触发一次。
- 当我将文件分配给
CurrentFrame
以测试数据绑定时,我
看到它似乎是 BitmapImage
类型——也许这就是
问题出在哪里??然而从我能收集到的信息来看,
BitmapSource 应该可以工作并在 WPF 视图中显示...
- 摄像头截取的画面不为空。我试着写它
直接到一个图像文件,它显示正确的内容为
预期。
编辑:
为了完整起见,这里也是视图的负责部分:
<UserControl.Resources>
<ResourceDictionary>
<local:CameraViewModel x:Key="vm" />
</ResourceDictionary>
</UserControl.Resources>
<Grid DataContext="{StaticResource vm}">
<Image Source="{Binding CurrentFrame}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
你不能设置
currentFrame = value;
打电话前
SetProperty(ref currentFrame, value);
因为支票
if (Object.Equals(storage, value)) return;
到时候永远是真的。
像这样实现 属性:
public BitmapSource CurrentFrame
{
get { return currentFrame; }
set { SetProperty(ref currentFrame, value); }
}
我只想捕捉并在我的视图中显示相机图片,每秒更新一次。但是,绑定到我的 Bitmapsource CurrentFrame
的图像容器在运行时保持空白。
到目前为止,这是我的代码(主要采用 an answer of another thread with similar topic:
public class CameraViewModel : ViewModelBase
{
public CameraViewModel()
{
StartVideo();
}
private DispatcherTimer Timer { get; set; }
private VideoCapture Capture { get; set; }
private BitmapSource currentFrame;
public BitmapSource CurrentFrame
{
get { return currentFrame; }
set
{
if (currentFrame != value)
{
currentFrame = value;
SetProperty(ref currentFrame, value);
}
}
}
private void StartVideo()
{
//CurrentFrame = new BitmapImage(new Uri("C:\Users\Johannes\Pictures\Camera Roll\asdf.bmp")) as BitmapSource;
Capture = new VideoCapture();
Timer = new DispatcherTimer();
//framerate of 10fps
Timer.Interval = TimeSpan.FromMilliseconds(1000);
Timer.Tick += new EventHandler(async (object s, EventArgs a) =>
{
//draw the image obtained from camera
using (Image<Bgr, byte> frame = Capture.QueryFrame().ToImage<Bgr, byte>())
{
if (frame != null)
{
CurrentFrame = ToBitmapSource(frame);
}
}
});
Timer.Start();
}
public static BitmapSource ToBitmapSource(IImage image)
{
using (System.Drawing.Bitmap source = image.Bitmap)
{
IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap
BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ptr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
DeleteObject(ptr); //release the HBitmap
return bs;
}
}
/// <summary>
/// Delete a GDI object
/// </summary>
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
}
一些为了更好理解的事情:
- ViewModelBase class 合并并处理 INotifyPropertyChange 事件。
- 数据绑定正在运行!我测试过
它,通过将 bmp 文件分配给
CurrentFrame
StartVideo()
方法 - 图像在运行时显示在 GUI 中。 SetProperty()
方法按预期每 1000 毫秒触发一次。- 当我将文件分配给
CurrentFrame
以测试数据绑定时,我 看到它似乎是BitmapImage
类型——也许这就是 问题出在哪里??然而从我能收集到的信息来看, BitmapSource 应该可以工作并在 WPF 视图中显示... - 摄像头截取的画面不为空。我试着写它 直接到一个图像文件,它显示正确的内容为 预期。
编辑: 为了完整起见,这里也是视图的负责部分:
<UserControl.Resources>
<ResourceDictionary>
<local:CameraViewModel x:Key="vm" />
</ResourceDictionary>
</UserControl.Resources>
<Grid DataContext="{StaticResource vm}">
<Image Source="{Binding CurrentFrame}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
你不能设置
currentFrame = value;
打电话前
SetProperty(ref currentFrame, value);
因为支票
if (Object.Equals(storage, value)) return;
到时候永远是真的。
像这样实现 属性:
public BitmapSource CurrentFrame
{
get { return currentFrame; }
set { SetProperty(ref currentFrame, value); }
}