【问题标题】:EmguCV: BitmapSource isn't updated on GUI after PropertyChanged Event:EmguCV:在 PropertyChanged 事件之后,BitmapSource 未在 GUI 上更新:
【发布时间】:2018-09-17 22:17:54
【问题描述】:

我想简单地捕捉并在我的视图上显示一张相机图片,每秒更新一次。但是,绑定到我的 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()Method - 图像在运行时显示在 GUI 中。
  3. SetProperty()Method 按预期每 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>

编辑2:Link to Github repository to view code

【问题讨论】:

  • 当我将文件分配给 CurrentFrame... 你的意思是图像是可见的?
  • @Clemens 是的,我没有使用从相机捕获的帧,而是加载了一个 bmp 文件并将其分配给 CurrentFramevariable。这样做 bmp 图像在 GUI 中可见。
  • 为什么 Tick 处理程序是异步的?似乎没有任何等待。
  • 您确定 Capture 确实返回非空图像,即不完全透明的图像吗?
  • 是的,我还测试了将捕获的帧直接写入文件 - 它显示了正确的内容。 - 我将在原始问题中进行编辑。

标签: c# wpf binding emgucv


【解决方案1】:

你不能设置

currentFrame = value;

打电话之前

SetProperty(ref currentFrame, value);

因为支票

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

那时将永远是真的。

像这样实现属性:

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

【讨论】:

  • 哦,伙计...如此明显且每次都被忽视:D 非常感谢!!
猜你喜欢
  • 2013-04-25
  • 2021-06-23
  • 1970-01-01
  • 2012-09-01
  • 1970-01-01
  • 2022-09-28
  • 2021-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多