![](/img/trans.png)
[英]Why StreamWriter dosent work good inside a paint event? Getting big red x in the pictureBox
[英]Picturebox getting big red X but I can't detect or fix it
我目前正在與AForge合作,並有一個新的幀事件,將幀作為位圖發布到圖片框中。 它有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次,有時它會在第二次點擊組合框時發生。 : - \\
任何人都可以解釋這里發生的事情,也許可以提出一個關於修復它的最佳方法的建議嗎? 我還是很新的線程,所以我一直在努力解決這里發生的事情以及解決問題的最佳方法! 任何朝着正確方向的推動都將是一個巨大的幫助!
最后,我在調用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
});
}
肖恩哈格里夫斯(Shawn Hargreaves)對“厄運的大紅色X”進行了精彩而簡潔的寫作 。 我發現在處理WinForm組件突然顯示紅色“X”的一般情況下,它非常有用。
綜上所述:
OnPaint
事件中拋出異常引起的。 OnPaint.
嘗試在使用位圖的地方使用克隆。 例如 :
videoPictureBox1.Image = (Bitmap)bitmap.Clone();
總而言之,這是一個經過測試的最低限度,即使在調整大小,啟動,停止或改變分辨率時,也沒有顯示紅十字。
public partial class PictureBoxVideo : Form
{
public PictureBoxVideo()
{
InitializeComponent();
var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
var videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString);
videoSource.NewFrame += Handle_Very_New_Frame;
videoSource.Start();
}
private void Handle_Very_New_Frame(object sender, NewFrameEventArgs eventArgs)
{
this.Invoke((MethodInvoker)delegate {
pictureBox.Image = new Bitmap(eventArgs.Frame);
});
}
}
請注意,我們稱之為videoSource.Start(); 來自GUI-(創建)-thread,但是從視頻(工作者)線程調用回調處理程序(Handle_Very_New_Frame)。
我認為這就是為什么我們需要兩個,Invoke和新的Bitmap,所以新的bmp也將從gui-thread生成。 但我只是在這里猜測,因為我無法提出證據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.