BrunoFerreira Posted December 12, 2022 at 02:34 PM Report Share #628746 Posted December 12, 2022 at 02:34 PM using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using AForge.Video; using AForge.Video.DirectShow; namespace VirtualFPVRemoteControl { public partial class MainForm : Form { //Global Var String[] serialLog = new String[300]; SerialLogDisplay sld_form; int motorPower = 0; FilterInfoCollection filterInfoCollection; VideoCaptureDevice videoCaptureDevice; //Form Method public MainForm() { InitializeComponent(); } //Generated Methods private void btnCCamera_Click(object sender, EventArgs e) { if(cmbCameraS.SelectedIndex > 0) { disconnectVideoStream(false); videoCaptureDevice = new VideoCaptureDevice(filterInfoCollection[cmbCameraS.SelectedIndex-1].MonikerString); videoCaptureDevice.NewFrame += new NewFrameEventHandler(VideoCaptureDevice_NewFrame); videoCaptureDevice.Start(); Add_Log("Camera \"" + filterInfoCollection[cmbCameraS.SelectedIndex-1].Name+ "\" Connected!"); } else { disconnectVideoStream(true); } } private void Form1_Load(object sender, EventArgs e) { //Camera System cmbCameraS.Items.Add("None"); filterInfoCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice); foreach (FilterInfo filterInfo in filterInfoCollection) { cmbCameraS.Items.Add(filterInfo.Name); } cmbCameraS.SelectedIndex = 0; videoCaptureDevice = new VideoCaptureDevice(); //Log shortLog.Parent = cameraDisplay; shortLog.BackColor = Color.Transparent; shortLog.Text = serialLog[0] + "\n" + serialLog[1] + "\n" + serialLog[2]; //Loop Timer tmr = new Timer(); tmr.Interval = 1000; tmr.Tick += Tmr_Tick; tmr.Start(); //DisplayObjects changeMPBar(motorPower); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { disconnectVideoStream(false); } private void SLbtn_Click(object sender, EventArgs e) { if (sld_form == null) { sld_form = new SerialLogDisplay(this); } sld_form.update_log(serialLog); sld_form.Show(); sld_form.Activate(); } private void closeBtn_Click(object sender, EventArgs e) { disconnectVideoStream(false); System.Windows.Forms.Application.Exit(); } private void minBtn_Click(object sender, EventArgs e) { this.WindowState = FormWindowState.Minimized; GC.Collect(); } //Created Methods //Serial Log private void Tmr_Tick(object sender, EventArgs e) { String lm = ""; for (int i = 4; i >= 0; i--) { if (serialLog[i] != null) { lm += serialLog[i] + "\n"; } } shortLog.Text = lm; } public void SerialLogDisplay_Close() { sld_form = null; } public void Add_Log(String text) { for (int i = serialLog.Length - 1; i > 0; i--) { serialLog[i] = serialLog[i - 1]; } serialLog[0] = text; if(sld_form != null) { sld_form.update_log(serialLog); } } public void Serial_Command(String command) { Add_Log(command); //Send command to serial Port } //Camera Output private void VideoCaptureDevice_NewFrame(object sender, NewFrameEventArgs eventArgs) { if (cameraDisplay.InvokeRequired) { try { cameraDisplay.Invoke((MethodInvoker)delegate { if (cameraDisplay.Image != null) { cameraDisplay.Image.Dispose(); } Bitmap bmp = (Bitmap)eventArgs.Frame.Clone(); cameraDisplay.Image = bmp; }); } catch (System.InvalidOperationException ex) { Add_Log("Error: " + ex); disconnectVideoStream(true); } } else { try { if (cameraDisplay.Image != null) { cameraDisplay.Image.Dispose(); } Bitmap bmp = (Bitmap)eventArgs.Frame.Clone(); cameraDisplay.Image = bmp; } catch (System.InvalidOperationException ex) { Add_Log("Error: " + ex); disconnectVideoStream(true); } } //GC.Collect(); } private void disconnectVideoStream(bool showLog) { if (videoCaptureDevice.IsRunning == true) { if (showLog) { Add_Log("Disconnecting video stream..."); } videoCaptureDevice.SignalToStop(); videoCaptureDevice.WaitForStop(); videoCaptureDevice.Stop(); cameraDisplay.Image = null; } if (showLog) { Add_Log("No camera connected!"); } GC.Collect(); } //Screen GUI private void changeMPBar(int nbar) { switch (nbar) { case 0: MPbar1.BackColor = Color.Transparent; MPbar2.BackColor = Color.Transparent; MPbar3.BackColor = Color.Transparent; MPbar4.BackColor = Color.Transparent; break; case 1: MPbar1.BackColor = Color.White; MPbar2.BackColor = Color.Transparent; MPbar3.BackColor = Color.Transparent; MPbar4.BackColor = Color.Transparent; break; case 2: MPbar1.BackColor = Color.White; MPbar2.BackColor = Color.White; MPbar3.BackColor = Color.Transparent; MPbar4.BackColor = Color.Transparent; break; case 3: MPbar1.BackColor = Color.White; MPbar2.BackColor = Color.White; MPbar3.BackColor = Color.White; MPbar4.BackColor = Color.Transparent; break; case 4: MPbar1.BackColor = Color.White; MPbar2.BackColor = Color.White; MPbar3.BackColor = Color.White; MPbar4.BackColor = Color.White; break; default: MPbar1.BackColor = Color.Transparent; MPbar2.BackColor = Color.Transparent; MPbar3.BackColor = Color.Transparent; MPbar4.BackColor = Color.Transparent; break; } } } } Eu tentei publicar esta dúvida no StackOverflow, mas a única resposta que tive foi de estar a usar a Picturebox(cameraDisplay) fora do Thread da UI. Para resumir o problema, a aplicação funciona normalmente, mas de vez em quando ela trava completamente ou então a imagem da pictureBox deixa de atualizar. Alguém sabe o motivo? Ou a forma correta de fazer? Link to comment Share on other sites More sharing options...
M6 Posted December 13, 2022 at 10:06 AM Report Share #628795 Posted December 13, 2022 at 10:06 AM Os problemas "de vez em quando" são dos mais difíceis de encontrar por não se saber como replicar. O melhor que posso dizer, por experiência, é que alguns tipos de recursos, como seja ligar a portas COM, acesso a dispositivos como câmaras, etc., é um tipo de interação que deve ser feito em thread própria, fora da thread principal da aplicação. 10 REM Generation 48K! 20 INPUT "URL:", A$ 30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50 40 PRINT "404 Not Found" 50 PRINT "./M6 @ Portugal a Programar." Link to comment Share on other sites More sharing options...
BrunoFerreira Posted December 13, 2022 at 03:03 PM Author Report Share #628817 Posted December 13, 2022 at 03:03 PM Em 13/12/2022 às 10:06, M6 disse: Os problemas "de vez em quando" são dos mais difíceis de encontrar por não se saber como replicar. O melhor que posso dizer, por experiência, é que alguns tipos de recursos, como seja ligar a portas COM, acesso a dispositivos como câmaras, etc., é um tipo de interação que deve ser feito em thread própria, fora da thread principal da aplicação. A libraria "AForge" cria um thread próprio para essa funcionalidade, o que disseram no stackOverflow foi que o problema podia ser de eu estar a aceder a picturebox,que está no thread da UI, do thread da criação de imagem criado pelo AForge. O código acima possui algum erro que em determinadas condições faz com que a imagem transmitida pare ou ,em casos mais graves, toda a aplicação deixe de responder sem lançar nenhuma exceção. 😔 //Camera Output //cameraDisplay -> PictureBox private void VideoCaptureDevice_NewFrame(object sender, NewFrameEventArgs eventArgs) { if (cameraDisplay.InvokeRequired) { try { cameraDisplay.Invoke((MethodInvoker)delegate { if (cameraDisplay.Image != null) { cameraDisplay.Image.Dispose(); } Bitmap bmp = (Bitmap)eventArgs.Frame.Clone(); cameraDisplay.Image = bmp; }); } catch (System.InvalidOperationException ex) { Add_Log("Error: " + ex); disconnectVideoStream(true); } } else { try { if (cameraDisplay.Image != null) { cameraDisplay.Image.Dispose(); } Bitmap bmp = (Bitmap)eventArgs.Frame.Clone(); cameraDisplay.Image = bmp; } catch (System.InvalidOperationException ex) { Add_Log("Error: " + ex); disconnectVideoStream(true); } } //GC.Collect(); } Link to comment Share on other sites More sharing options...
M6 Posted December 15, 2022 at 10:24 AM Report Share #628926 Posted December 15, 2022 at 10:24 AM É diria que é mais do mesmo, a atualização da imagem deve estar numa thread própria. 10 REM Generation 48K! 20 INPUT "URL:", A$ 30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50 40 PRINT "404 Not Found" 50 PRINT "./M6 @ Portugal a Programar." Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now