10

私は現在 AForge を使用しており、フレームをビットマップとしてピクチャボックスに投稿する on new frame イベントがあります。90% の確率で問題なく動作します... winform で何かをいじらない限り。コンボ ボックスの変更、ウィンドウの移動などを行うと、Picturebox がビデオから大きな赤い X に切り替わる危険があります。以下のコード サンプル:

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

if (videoPictureBox1.Image == videoPictureBox1.ErrorImage) にブレークを設定すると、画像が実際にビットマップに設定されているため、大きな赤い X が上にある場合でも false と評価されます。したがって、 cam.Stop() と cam.Start() は実行されません (それが役立つかどうかはわかりませんが、試してみることにしました)。

videoPictureBox1.Refresh() は毎回実行されていますが、やはり違いはありません。まだ大きな赤い X があります。

前に言ったように、ビデオを開始して何も触れないと、大きな赤い X は表示されません。しかし、コンボ ボックスを変更したり、フォーム自体をドラッグしたりすると、大きな赤い X が表示される可能性が指数関数的に上がります。コンボ ボックスを 10 ~ 12 回めくってから、コンボ ボックスを 10 ~ 12 回めくることができます。:-\

誰かがここで何が起こっているのかを説明し、おそらくそれを修正するための最良の方法について提案できますか? 私はまだスレッド化に非常に慣れていないので、ここで何が起こっているのか、問題を解決する最善の方法を正確に理解するのに苦労しています! 正しい方向へのナッジは大きな助けになるでしょう!

4

4 に答える 4

6

最後に、呼び出しですべてを Handle_New_Frame にラップしました。大きな赤い X の問題を永久に完全に削除しました。>_>

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
  });
}
于 2013-04-22T19:41:57.873 に答える
6

Shawn Hargreaves は、「破滅の大きな赤い X」について、優れた簡潔な記事を書いています。突然赤い「X」が表示される WinForm コンポーネントを処理する一般的なケースで非常に役立つことがわかりました。

要約すれば:

  • OnPaintこれは、コントロールがイベントから例外をスローしたことが原因です。
  • スローされると、そのコントロールは引き続き赤い X を表示し、発砲をスキップします。OnPaint.
  • デバッグするには、共通言語ランタイムの例外をキャッチするようにデバッガーを設定し、赤い X を取得するために通常行っていることをすべて実行します。
于 2015-04-22T21:26:00.053 に答える
1

ビットマップを使用する場所でクローンを使用してみてください。

videoPictureBox1.Image = (Bitmap)bitmap.Clone();
于 2013-04-18T19:37:16.507 に答える