WPF 图像的持续(快速)更新
有一个网站包含来自网络摄像头的单个图像。每次访问该网站时,都会显示网络摄像头的最新图像。我想通过连续访问该网站来制作实时视频。
我已经搜索并尝试了几件事,但无法让它以合理的速度刷新。
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
查看我对此的回答:显示来自 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.
我建议位图图像是在非 GUI 线程上创建的依赖对象。然后,您可以在 GUI 线程上调用 UpdateImage。由于位图图像依赖对象不是在 GUI 线程上创建的/(由 GUI 线程拥有),因此您会收到“不同的线程拥有它”错误。
作为一种解决方法怎么样?
Thread.Sleep
添加到监视例程中,这样您就不会因为该线程上的无限循环而对 CPU 造成影响。BeginInvoke
而不是Invoke
。在不知道如何让 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?
Thread.Sleep
to the watch routine so that you don't hammer the CPU with the endless loop on this thread.BeginInvoke
instead ofInvoke
.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.
这个应用程序总是会挂起(无论是 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!)
尝试仅更改 UriSource 属性,而不是重新创建整个图像。
instead of recreating whole image try to change only UriSource property.