在 WPF 中显示来自我的网络摄像头的视频流?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36890103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:46:26  来源:igfitidea点击:

Displaying a videostream from my webcam in WPF?

c#wpfmvvmcaliburn.microemgucv

提问by Esteban Chamard

I have a question, how can I display the stream from my webcam in a Image container in WPF ? I already get the stream with Emgu and converted it to an BitmapSource, but now I don't understand how to bind an Image from my webcam to WPF, with caliburn (MVVM) , every X ms ....

我有一个问题,如何在 WPF 的图像容器中显示来自我的网络摄像头的流?我已经使用 Emgu 获取了流并将其转换为 BitmapSource,但现在我不明白如何将图像从我的网络摄像头绑定到 WPF,使用 caliburn (MVVM) ,每 X ms ....

 <Image x:Name="imageWebcam" />

采纳答案by Esteban Chamard

Ok solution found. I can't show the whole code but I can explain a little bit, to bind wpf View:

好的解决方案找到了。我无法显示整个代码,但我可以解释一下,绑定 wpf 视图:

<Image x:Name="ImageWebcam" />

To my ViewModel (using Caliburn FrameWork, but this can be easily adapted to an MVVM pattern) I must bind the Image with a function having the same name :

对于我的 ViewModel(使用 Caliburn FrameWork,但这可以很容易地适应 MVVM 模式)我必须将 Image 与具有相同名称的函数绑定:

    public WriteableBitmap ImageWebcam
    {
        get
        {
            return this.imageWebcam;
        }
        set
        {
            this.imageWebcam = value;
            this.NotifyOfPropertyChange(() => this.ImageWebcam);
        }
    }

And to update this Image I use a Timer, that must be initialize into the ViewModel constructor :

为了更新这个图像,我使用了一个定时器,它必须被初始化到 ViewModel 构造函数中:

public MachinBidule()
{
    timeIsRunningOut= new System.Timers.Timer();
    timeIsRunningOut.AutoReset = true;
    timeIsRunningOut.Interval = 10;
    timeIsRunningOut.Elapsed += (sender, e) => { UpdateImage(); };
    capture = new Capture();   // Capture the webcam using EmguCV
}

And now you can manage the update using a dispatcher :

现在您可以使用调度程序管理更新:

// Update the image, method called by the timer every 10 ms 
private void UpdateImage()
{
    // If capture is working
    if(capture.QueryFrame()!= null)
    {
        //capture an Image from webcam stream and 
        Image<Bgr, Byte> currentFrame = capture.QueryFrame().ToImage<Bgr, Byte>();
        if (currentFrame != null)
        {
            Application.Current.Dispatcher.BeginInvoke(new System.Action(() => { imageWebcam = new WriteableBitmap(BitmapSourceConvert.ToBitmapSource(currentFrame)); NotifyOfPropertyChange(() => ImageWebcam); }));
        }
    }
}

You can notice that we need to convert from emguCV Image<Bgr,Byte>to WPF WriteableBitmapand notify the update with NotifyOfPropertyChange(() => ImageWebcam).

您可以注意到我们需要从 emguCV 转换Image<Bgr,Byte>为 WPFWriteableBitmap并使用NotifyOfPropertyChange(() => ImageWebcam).

Please feel free to contact me or comment if you have any questions. If you've noticed any mistake don't hesitate to correct me (grammar & code).

如果您有任何问题,请随时与我联系或发表评论。如果您发现任何错误,请随时纠正我(语法和代码)。

回答by StepUp

You should use MediaElementto show video, not Imagecontrol:

您应该使用MediaElement来显示视频,而不是Image控制:

XAML:

XAML:

<MediaElement Source="{Binding VideoAddress}" />

viewModel:

视图模型:

private URI videoAddress=new URI("C:\video.wmv");
public URI VideoAddress
{
   get { return videoAddress; }
   set
   {
       videoAddress = value; 
       OnPropertyChanged("LeafName");
   }
}

Also, you can use WPF-MediaKitto show video from WebCam. Or see this tutorial.

此外,您可以使用WPF-MediaKit来显示来自网络摄像头的视频。或查看本教程

Update:

更新:

You should use Image, to show an image:

您应该使用Image, 来显示图像:

<Image x:Name="imageWebcam" />

and C#:

和 C#:

BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri("C:/1.png");
logo.EndInit();

imageWebcam.Source = logo;

回答by Simon Wood

Use a WriteableBitmap as the source of your image element. You should provide a callback in your view model that passes the frame data for each new frame. Subscribe to this callback from your view in the code behind. You can then write each frame to the bitmap. I don't think data binding is a good approach in this case.

使用 WriteableBitmap 作为图像元素的来源。您应该在视图模型中提供一个回调,为每个新帧传递帧数据。在后面的代码中从您的视图订阅此回调。然后您可以将每一帧写入位图。在这种情况下,我认为数据绑定不是一个好方法。

When dealing with a stream of video frames WriteableBitmap is by far the best option in WPF:

在处理视频帧流时,WriteableBitmap 是 WPF 中迄今为止最好的选择:

WriteableBitmap

可写位图