Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF image stop repainting

Using WPF and MVVM I'm trying to display camera images into a Image. Each frame camera got, a callback is called :

Viewmodel

public void OnNewFrame(object sender, EventArgs e)
{
    Camera camera = sender as MyCamera;
    camera.ToBitmap(out _bmpImage);
    RaisePropertyChanged("BMPImage");
}

Each frame, I update the variable _bmpImage :

ViewModel

private Bitmap _bmpImage;
public Bitmap BMPImage
{
    get
    { return _bmpImage; }
    private set
    { _bmpImage = value; RaisePropertyChanged("BMPImage"); }
}

In order to convert the Bitmap to BitmapImage I use a converter :

Converter

public class ImageToSource : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter,
                System.Globalization.CultureInfo culture)
        {
            Image image = value as Image;
            if (image != null)
            {
                MemoryStream ms = new MemoryStream();
                image.Save(ms, ImageFormat.Bmp);
                ms.Seek(0, SeekOrigin.Begin);
                BitmapImage bi = new BitmapImage();
                bi.BeginInit();
                bi.StreamSource = ms;
                bi.EndInit();
                return bi;
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType,
            object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
  }

Finnaly bind to my view :

 <Image Source="{Binding Main.BMPImage, Converter={StaticResource ImageToSource}}"></Image>

It's work good the 15 first second, but after this delay : my Image becomes white. In the Converter, image is never null so camera works well. The problem is the component Image stop repainting.
When the Image is white, I can resize the window or move it and the image becomes good because Image is repainting.

There is something I do wrong ?
There are a way to force Image repainting ?
Why Image stop repainting ?

Thanks

EDIT1:

After some verification, when image becomes white, all ui freeze (so my button are not clickable until I resize or move the window)

EDIT2

as Dennis in the comment suggered me, I tryed to do the conversion in my ViewModel :

For that, I add a property which represent the converted image :

 private BitmapImage _testImage;
 public BitmapImage TestImage
 {
      get
      { return _testImage; }
      private set
      { _testImage = value; RaisePropertyChanged("TestImage"); }
 }

And I converted _bmpImage directly into OnNewFrame :

public void OnNewFrame(object sender, EventArgs e)
    {
        Camera camera = sender as MyCamera;
        camera.ToBitmap(out _bmpImage);
        //RaisePropertyChanged("BMPImage");
        if (_bmpImage != null)
        {
              // Convertion
              MemoryStream ms = new MemoryStream();
              _bmpImage.Save(ms, ImageFormat.Bmp);
              ms.Seek(0, SeekOrigin.Begin);
              _testImage = new BitmapImage();
              _testImage.BeginInit();
              _testImage.StreamSource = ms;
              _testImage.EndInit();
              RaisePropertyChanged("TestImage");
        }
    }

and bind directly the TestImage on my Image
View

<Image Source="{Binding Main.TestImage}" />

And with this code I've the exception :

Must create DependencySource on same Thread as the DependencyObject

EDIT 3

I have considered your remarks and it's my new code :

if (_bmpImage != null)
            {

                // Convertion
                Console.WriteLine("ok");
                MemoryStream ms = new MemoryStream();
                _bmpImage.Save(ms, ImageFormat.Bmp);
                ms.Seek(0, SeekOrigin.Begin);
                _testImage = new BitmapImage();
                _testImage.BeginInit();
                _testImage.StreamSource = ms;
                _testImage.EndInit();

                ms.Dispose();

                System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)(() =>
                {
                    RaisePropertyChanged("TestImage");
                }));

            }

I've the same exception on RaisePropertyChanged("TestImage");

Juste note that Edit2 and Edit3 are a test and doesn't answer to the my original question

Sorry for the long post

like image 528
Epitouille Avatar asked Jun 05 '15 09:06

Epitouille


1 Answers

I'll bet Your OnNewFrame method does not run on the UI thread.

In your code, change this line so it runs on the UI thread buy calling Invoke or BeginInvoke on the Dispatcher property of your window / control:

windowOrControlDispatcher.BeginInvoke((Action) (() =>
{
    RaisePropertyChanged("TestImage");
}));
like image 58
James Harcourt Avatar answered Oct 21 '22 21:10

James Harcourt