2011-05-03 263 views
2

有一个网站包含一个来自网络摄像机的单个图像。每次点击该网站时,都会显示网络摄像机的最新图像。我想通过不断点击该网站制作实时视频。WPF Image的连续(快速)更新

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

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); 
    } 
} 

问题是,这太慢了,需要很长时间才能刷新和应用程序挂起。

我得到这个在Windows窗体中使用PictureBox控件工作,但无法让它在WPF中工作。我拒绝相信WPF不如形式。

回答

0

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

1

这个应用程序将永远只是挂起(无论是winforms或WPF),因为你有一个无限循环运行它在UI线程上做的一切。您的应用程序因为您不允许UI线程随时处理用户输入(例如调整窗口大小或尝试关闭应用程序)而挂起。

关于你的表现:你有没有尝试分析你的代码?我怀疑问题在于你反复抨击图像的网络服务器,因为你永远无法获得足够的每秒请求数,从静态图像制作任何类型的实时视频。 (有一个原因,我们有视频流编解码器!)

0

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

这是一个解决方法呢?

  1. 将图像临时复制到Watch例程中的本地文件位置。
  2. 将一个Thread.Sleep添加到手表程序,以便您不要在该线程上用无限循环敲击CPU。使用BeginInvoke代替Invoke
  3. 加载并更新UpdateImage例程中的图像,以使图像和imgVideo对象位于GUI线程上。通过从本地文件副本中读取图像来更新图像。

不知道你是怎么做的具体细节Watch在自己的线程上运行(使用Background worker?)我认为这种方法适用于你。