jack1818
jack1818

Reputation: 21

Continual (rapid) update of WPF Image

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.

Upvotes: 2

Views: 2449

Answers (4)

Allen
Allen

Reputation: 53

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.

Upvotes: 0

Danny Varod
Danny Varod

Reputation: 18118

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

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

Upvotes: 0

Dan Puzey
Dan Puzey

Reputation: 34218

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!)

Upvotes: 1

Eugen
Eugen

Reputation: 2990

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

Upvotes: 0

Related Questions