Error: Invalid thread operation

2

I'm trying to open the Webcam, however every time I try to execute the iniciarwebcam() method it returns me the error:

  

An exception of type "System.InvalidOperationException" occurred in   System.Windows.Forms.dll, but it has not been manipulated in   Invalid Interstring Operation: Control 'Form1' accessed from   a thread that is not the one in which it was created.

As I'm learning C # right now with difficulties of finding a solution that fit my

The error happens on the line:

video.NewFrame += (s, b) => pictureBox1.Image = (Bitmap)b.Frame.Clone();

Code:

using AForge.Video.DirectShow;

public void  inciarwebcam() 
{

    FilterInfoCollection filtro = new FilterInfoCollection(FilterCategory.VideoInputDevice);

    if (filtro != null)
    {
        video = new VideoCaptureDevice(filtro[0].MonikerString);
        video.NewFrame += (s, b) => pictureBox1.Image = (Bitmap)b.Frame.Clone();
        video.Start();
    }
}

public void fecharwebcam() 
{

    if (video != null && video.IsRunning ) {

        video.SignalToStop();
        video = null;

    }

}

public VideoCaptureDevice video;

private void button6_Click(object sender, EventArgs e)
{
    if (button6.Text == "Desativado")
    {
        button6.Text = "Ativado";
        button6.BackColor = Color.Green;
       ard.Open();
        inciarwebcam();
    }
    else
    {
        button6.BackColor = Color.DarkRed;
        button6.Text = "Desativado";
        ard.Close();

        fecharwebcam();
    };
}
    
asked by anonymous 23.08.2018 / 19:10

2 answers

4

Possibly the NewFrame event is asynchronous, and when trying to access pictureBox1 the exception is triggered.

You can use an invoke for this:

video.NewFrame += (s, b) => pictureBox1.Invoke((MethodInvoker) delegate {
                            pictureBox1.Image = (Bitmap)b.Frame.Clone();
            });

It seems that this way can get a bit slow, since every frame will go in the other thread to show the image. It's just a starting point, if you have documentation of what you're using it can make things easier

Edit:

I have a form with the same library, and in the example I used, there is a variable in form, which receives the image, and then it is applied to picturebox :

Bitmap Imagem;
private void video_NovoFrame(object sender, NewFrameEventArgs eventArgs)
{
    Imagem = (Bitmap)eventArgs.Frame.Clone();
    pbCaptura.Image = Imagem;
}
    
23.08.2018 / 19:20
0

You can always validate whether the control actually needs to evoke Invoke :

video.NewFrame += (s, b) => 
{
    if(pictureBox1.InvokeRequired)
        pictureBox1.Invoke(new Action(() => { pictureBox1.Image = (Bitmap)b.Frame.Clone(); }));
    else pictureBox1.Image = (Bitmap)b.Frame.Clone();
}
    
23.08.2018 / 19:23