Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Picturebox getting big red X but I can't detect or fix it

I am currently working with AForge, and have an on new frame event that posts the frame, as a bitmap, into a picturebox. 90% of the time it works great... UNLESS I fiddle with something on the winform. Changing a combo box, moving the window, or anything like that risks causing the Picturebox to switch from the video to a big red X. Code sample below:

    private void connectButton_Click(object sender, EventArgs e)
    {
        try
        {
            cam = new VideoCaptureDevice(captureDevices[CameraSelectComboBox.SelectedIndex].MonikerString);
            cam.NewFrame -= Handle_New_Frame; //Just to avoid the possibility of a second event handler being put on
            cam.NewFrame += new AForge.Video.NewFrameEventHandler(Handle_New_Frame);
            cam.Start();
        }
        catch
        {
            MessageBox.Show("An error has occured with connecting to the specified webcam. The application will now close!");
            Application.Exit();
        }
    }

    private void Handle_New_Frame(object sender, NewFrameEventArgs eventArgs)
    {

        try
        {
            if (bitmap != null)
                bitmap.Dispose(); //Without this, memory goes nuts
            bitmap = new Bitmap(eventArgs.Frame);
        }
        catch { }

        //Draw some stuff on the images
        bitmap = AdjustBrightness(bitmap, brightnessMeter);
        bitmap = ApplyContrast(contrastMeter, bitmap);
        bitmap = Draw_Top_Line(bitmap);
        bitmap = Draw_Bottom_Line(bitmap);

        //Set the image into the picturebox
        this.Invoke((MethodInvoker)delegate
        {
            videoPictureBox1.Image = bitmap;
            frameRate++; //Keep track of the frame rate
        });

        GC.Collect(); //Without this, memory goes nuts

        this.Invoke((MethodInvoker)delegate {
            videoPictureBox1.Refresh(); //NOT NECESSARY. JUST TRYING TO FIX THE BIG RED X!
        });

        if (videoPictureBox1.Image == videoPictureBox1.ErrorImage)
        {
            cam.Stop(); //ALSO NOT NECESSARY> AGAIN, JUST TRYING TO FIX THE BIG RED X!
            cam.Start();
        }
    }

I put a break on the if (videoPictureBox1.Image == videoPictureBox1.ErrorImage) and it is evaluating to false, even when the big red X is up, because the image is actually being set to the bitmap. So cam.Stop() and cam.Start() never run (not sure if that would even help, but I figured I would give it a try).

videoPictureBox1.Refresh() is running every time, but again- it's not making a difference. Still have the big red X.

As I said before: if I start the video and touch nothing, the big red X will never happen. But the moment I start changing combo boxes, or dragging the form itself around, the chance of the big red X goes up exponentially. Sometimes I can flip through the combo box 10-12 times before it happens, other times it happens the second I click the combobox. :-\

Can anyone explain what is happening here and perhaps offer a suggestion on the best method to go about fixing it? I'm still very new to threading, so I've been struggling to wrap my head around exactly what is happening here and the best way to fix the issue! Any nudges in the right direction would be a huge help!

like image 821
C Smith Avatar asked Apr 17 '13 13:04

C Smith


1 Answers

In the end, I wrapped EVERYTHING in in the Handle_New_Frame in an invoke. It completely removed the big red X issue, permanently. >_>

private void Handle_New_Frame(object sender, NewFrameEventArgs eventArgs)
{
  this.Invoke((MethodInvoker)delegate
  {
    try
    {
        if (bitmap != null)
        {
            bitmap.Dispose(); //Without this, memory goes nuts
        }

        bitmap = new Bitmap(eventArgs.Frame);
    }
    catch { }

    //Draw some stuff on the images
    bitmap = AdjustBrightness(bitmap, brightnessMeter);
    bitmap = ApplyContrast(contrastMeter, bitmap);
    bitmap = Draw_Top_Line(bitmap);
    bitmap = Draw_Bottom_Line(bitmap);

    //Set the image into the picturebox
    this.Invoke((MethodInvoker)delegate
    {
        videoPictureBox1.Image = bitmap;
        frameRate++; //Keep track of the frame rate
    });

    GC.Collect(); //Without this, memory goes nuts
  });
}
like image 86
C Smith Avatar answered Oct 05 '22 04:10

C Smith