WPF 图像的持续(快速)更新

发布于 2024-11-04 07:59:53 字数 1495 浏览 0 评论 0原文

有一个网站包含来自网络摄像头的单个图像。每次访问该网站时,都会显示网络摄像头的最新图像。我想通过连续访问该网站来制作实时视频。

我已经搜索并尝试了几件事,但无法让它以合理的速度刷新。

public MainWindow()
{
  InitializeComponent();

  this.picUri = "http://someurl";
  this.thWatchVideo = new Thread(new ThreadStart(Watch));

  _image = new BitmapImage();
  _image.BeginInit();
  _image.CacheOption = BitmapCacheOption.None;
  _image.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
  _image.CacheOption = BitmapCacheOption.OnLoad;
  _image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
  _image.UriSource = new Uri(this.picUri);
  _image.EndInit();
  this.imgVideo.Source = _image;

  this.thWatchVideo.Start();
}

public void Watch()
{
   while(true)
   {
     UpdateImage();
   }
}

 public void UpdateImage()
{
  if (this.imgVideo.Dispatcher.CheckAccess())
  {
     _image = new BitmapImage();
     _image.BeginInit();
     _image.CacheOption = BitmapCacheOption.None;
     _image.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
     _image.CacheOption = BitmapCacheOption.OnLoad;
     _image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
     _image.UriSource = new Uri(this.picUri);
     _image.EndInit();
     this.imgVideo.Source = _image;
  }
  else
  {
    UpdateImageCallback del = new UpdateImageCallback(UpdateImage);
    this.imgVideo.Dispatcher.Invoke(del);
  }
}

问题是,这太慢了,刷新时间太长,而且应用程序挂起。

我让它在带有 PictureBox 控件的 Windows 窗体中工作,但无法在 WPF 中工作。我不相信 WPF 不如表单。

There is a website that contains a single image from a webcam. Each time the site is hit, the most current image of the webcam is displayed. I want to make a real time video by hitting the site continuously.

I have searched and tried several things but cannot get it to refresh at a reasonable rate.

public MainWindow()
{
  InitializeComponent();

  this.picUri = "http://someurl";
  this.thWatchVideo = new Thread(new ThreadStart(Watch));

  _image = new BitmapImage();
  _image.BeginInit();
  _image.CacheOption = BitmapCacheOption.None;
  _image.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
  _image.CacheOption = BitmapCacheOption.OnLoad;
  _image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
  _image.UriSource = new Uri(this.picUri);
  _image.EndInit();
  this.imgVideo.Source = _image;

  this.thWatchVideo.Start();
}

public void Watch()
{
   while(true)
   {
     UpdateImage();
   }
}

 public void UpdateImage()
{
  if (this.imgVideo.Dispatcher.CheckAccess())
  {
     _image = new BitmapImage();
     _image.BeginInit();
     _image.CacheOption = BitmapCacheOption.None;
     _image.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
     _image.CacheOption = BitmapCacheOption.OnLoad;
     _image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
     _image.UriSource = new Uri(this.picUri);
     _image.EndInit();
     this.imgVideo.Source = _image;
  }
  else
  {
    UpdateImageCallback del = new UpdateImageCallback(UpdateImage);
    this.imgVideo.Dispatcher.Invoke(del);
  }
}

Problem is, this is too slow and takes too long to refresh and the app just hangs.

I got this to work in Windows Forms with the PictureBox control but cannot get it to work in WPF. I refuse to believe that WPF is inferior to forms.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

╰沐子 2024-11-11 07:59:55

查看我对此的回答:显示来自 IP 摄像机的处理后的图像

另外,请确保通信是在单独的线程上完成的。

Check out my answer to this: Showing processed images from an IP camera

Also, make sure the communication is done on a separate thread.

此岸叶落 2024-11-11 07:59:55

我建议位图图像是在非 GUI 线程上创建的依赖对象。然后,您可以在 GUI 线程上调用 UpdateImage。由于位图图像依赖对象不是在 GUI 线程上创建的/(由 GUI 线程拥有),因此您会收到“不同的线程拥有它”错误。

作为一种解决方法怎么样?

  1. 将图像临时复制到 Watch 例程中的本地文件位置。
  2. Thread.Sleep 添加到监视例程中,这样您就不会因为该线程上的无限循环而对 CPU 造成影响。
  3. 使用 BeginInvoke 而不是 Invoke
  4. 在 UpdateImage 例程中加载并更新图像,以便图像和 imgVideo 对象位于 GUI 线程上。通过从本地文件副本读取图像来更新图像。

在不知道如何让 Watch 在自己的线程上运行的具体情况(使用后台工作程序?)的情况下,我认为这种方法适合您。

I suggest that the Bitmap image is a dependency object being created on a non-GUI thread. You then invoke UpdateImage on the GUI thread. Since the bitmap image dependency object wasn't created on/(owned by) the GUI thread, you get the "different thread owns it" error.

How about this as a workaround?

  1. Copy the image temporarily to a local file location in your Watch routine.
  2. Add a Thread.Sleep to the watch routine so that you don't hammer the CPU with the endless loop on this thread.
  3. Use BeginInvoke instead of Invoke.
  4. Load and update the image in the UpdateImage routine so that the image and the imgVideo objects are on the GUI thread. Update the image by reading it from your local file copy.

Without knowing the specifics of how you make Watch run on its own thread (using Background worker?) I think this approach will work for you.

我ぃ本無心為│何有愛 2024-11-11 07:59:54

这个应用程序总是会挂起(无论是 winforms 还是 WPF),因为你有一个无限循环运行它在 UI 线程上执行的所有操作。您的应用程序挂起是因为您不允许 UI 线程任何时候处理用户输入(例如调整窗口大小或尝试关闭应用程序)。

关于您的性能:您是否尝试过分析您的代码?我怀疑问题在于您反复敲击网络服务器来获取图像,因为您永远不可能获得足够的每秒请求来从静态图像制作任何类型的实时视频。 (我们拥有视频流编解码器是有原因的!)

This app will always just hang (whether winforms or WPF) because you've got an infinite loop running everything it does on the UI thread. Your app hangs because you're not allowing the UI thread any time to process user input (such as resizing the window or trying to close the app).

With regard to your performance: have you tried profiling your code? I suspect that the problem is to do with you repeatedly hammering a webserver for an image, since you're never likely to get enough requests-per-second to make any kind of real-time video from static images. (There's a reason that we have video streaming codecs!)

甜尕妞 2024-11-11 07:59:54

尝试仅更改 UriSource 属性,而不是重新创建整个图像。

instead of recreating whole image try to change only UriSource property.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文