EmguCV:PropertyChanged事件后,GUI上未更新BitmapSource:

时间:2018-09-17 12:19:21

标签: c# wpf binding emgucv

我想简单地捕获并显示我的视图中的相机图像,并每秒更新一次。但是,绑定到我的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);

}

一些需要更好理解的东西:

  1. ViewModelBase类可以协同工作并处理 INotifyPropertyChange事件。
  2. 数据绑定正在工作!我测试过     通过将bmp文件分配给CurrentFrame     StartVideo()方法-运行时图像显示在GUI中。
  3. SetProperty()方法按预期每1000毫秒触发一次。
  4. 当我将文件分配给CurrentFrame来测试数据绑定时,我 看到它似乎是BitmapImage类型的-也许就是 问题出在哪里?但是,从我可以收集的信息中, BitmapSource应该可以工作并在WPF视图中显示...
  5. 从相机捕获的帧不为空。我试图写 直接将其显示为图像文件,并显示正确的内容为 预期的。

编辑: 为了完整起见,这也是视图的负责部分:

<UserControl.Resources>
    <ResourceDictionary>
        <local:CameraViewModel x:Key="vm" />
    </ResourceDictionary>
</UserControl.Resources>

<Grid DataContext="{StaticResource vm}">
    <Image Source="{Binding CurrentFrame}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>

Edit2:Link to Github repository to view code

1 个答案:

答案 0 :(得分:2)

您不得设置

currentFrame = value;

在致电之前

SetProperty(ref currentFrame, value);

因为支票

if (Object.Equals(storage, value)) return;

那么永远都是真的。

像这样实现属性:

public BitmapSource CurrentFrame
{
    get { return currentFrame; }
    set { SetProperty(ref currentFrame, value); }
}