C3032
2026-01-08 7279c77f318cd7e38af279dc98a1fecec33f5e30
LB_VisionProcesses/Cameras/2DCameraForm.cs
@@ -252,7 +252,18 @@
                        return;
                }
                if (cmbSN.Items.Count > 0 && camera.InitDevice(cmbSN.Text.ToString(), this.Handle))
                IntPtr displayHandle = onlinePictureBox.Handle;
                if (brand == CameraBrand.LBCamera)
                {
                    onlinePictureBox.Visible = false;
                    displayHandle = this.panel_Picture.Handle;
                }
                else
                {
                    onlinePictureBox.Visible = true;
                }
                if (cmbSN.Items.Count > 0 && camera.InitDevice(cmbSN.Text.ToString(), displayHandle))
                {
                    camera.ImageGrabbed -= GetImageBllComplete;
                    camera.ImageGrabbed += GetImageBllComplete;
@@ -295,8 +306,10 @@
            if (camera.CloseDevice())
            {
                onlinePictureBox.Visible = true;
                MessageBox.Show(camera.SN + "断开成功");
                this.panel_Picture.Controls.Clear();
                this.panel_Picture.Controls.Add(onlinePictureBox);
            }
        }
@@ -382,28 +395,42 @@
        /// <summary>
        /// 相机回调运行
        /// 注意:对于LBCamera(3D线扫相机),使用SDK自动显示模式
        /// SDK会自动将图像显示到对应的控件上,此回调只用于统计采集次数
        /// </summary>
        /// <param name="CCDName"></param>
        /// <param name="image"></param>
        private void GetImageBllComplete(object sender, CameraEventArgs e)
        {
            // 对于LBCamera(SDK自动显示模式),Bitmap为null,我们只需要统计
            if (camera.Brand == CameraBrand.LBCamera)
            {
                if (e is LBCameraEventArgs args && args.IsComplete)
                {
                    total.iImageCount++;
                    // 不需要更新onlinePictureBox.Image,SDK会自动显示
                }
                return;
            }
            // 对于2D相机(手动处理模式)
            if (e.Bitmap == null)
                return;
                lock (e.Bitmap)
            lock (e.Bitmap)
            {
                if (this.InvokeRequired) // 检查是否需要在UI线程上调用
                {
                    if (this.InvokeRequired) // 检查是否需要在UI线程上调用
                    {
                        this.Invoke(new Action(() =>
                        {
                            onlinePictureBox.Image = e.Bitmap;
                        })); // 递归调用自身,但这次在UI线程上
                    }
                    else
                    this.Invoke(new Action(() =>
                    {
                        onlinePictureBox.Image = e.Bitmap;
                    }
                    })); // 递归调用自身,但这次在UI线程上
                }
                else
                {
                    onlinePictureBox.Image = e.Bitmap;
                }
            }
            total.iImageCount++;
            try
            {
@@ -426,23 +453,121 @@
            Task.Factory.StartNew(() =>
            {
                //camera.GetCamConfig(out CameraConfig OriCamConfig);
                // 设置曝光和增益
                camera.SetExpouseTime(Convert.ToDouble(txtExp.Text));
                camera.SetGain(Convert.ToDouble(txtGain.Text));
                camera.GetImageWithSoftTrigger(out Bitmap bitmap);
                bool success = false;
                Bitmap bitmap = null;
                this.BeginInvoke(new Action(() =>
                // 调用基类接口的单次采集方法
                // LBCamera重写了StartSingleGrab方法,其他相机调用返回false
                success = camera.StartSingleGrab();
                if (success)
                {
                    if (bitmap != null)
                        this.lblCapTime.Text = $"{(DateTime.Now - StartTime).TotalMilliseconds}ms";
                    else
                        this.lblCapTime.Text = "-1ms";
                }));
                    // 对于LBCamera(SDK自动显示模式),等待采集完成即可
                    // 对于2D相机,等待Bitmap事件
                    if (camera.Brand == CameraBrand.LBCamera)
                    {
                        // SDK自动显示模式下,等待采集完成
                        using (AutoResetEvent waitHandle = new AutoResetEvent(false))
                        {
                            bool captured = false;
                            EventHandler<CameraEventArgs> handler = (s, evt) =>
                            {
                                if (evt is LBCameraEventArgs args && args.IsComplete)
                                {
                                    captured = true;
                                    waitHandle.Set();
                                }
                            };
                //复原原通讯口设置
                //camera.SetCamConfig(OriCamConfig);
                            camera.ImageGrabbed += handler;
                            try
                            {
                                // 等待5秒超时
                                if (waitHandle.WaitOne(5000))
                                {
                                    // SDK自动显示模式,不返回Bitmap
                                    // 但采集已完成
                                }
                                this.BeginInvoke(new Action(() =>
                                {
                                    this.lblCapTime.Text = $"{(DateTime.Now - StartTime).TotalMilliseconds}ms";
                                }));
                            }
                            finally
                            {
                                camera.ImageGrabbed -= handler;
                                camera.StopGrabbing();
                            }
                        }
                    }
                    else
                    {
                        // 对于2D相机,等待图像数据
                        using (AutoResetEvent waitHandle = new AutoResetEvent(false))
                        {
                            Bitmap captured = null;
                            EventHandler<CameraEventArgs> handler = (s, evt) =>
                            {
                                // 对于2D相机,直接接收图像
                                if (!(evt is LBCameraEventArgs) && evt.Bitmap != null)
                                {
                                    captured = evt.Bitmap.Clone() as Bitmap;
                                    waitHandle.Set();
                                }
                            };
                            camera.ImageGrabbed += handler;
                            try
                            {
                                // 等待5秒超时
                                if (waitHandle.WaitOne(5000))
                                {
                                    bitmap = captured;
                                }
                            }
                            finally
                            {
                                camera.ImageGrabbed -= handler;
                                camera.StopGrabbing();
                            }
                        }
                        this.BeginInvoke(new Action(() =>
                        {
                            if (bitmap != null)
                            {
                                this.lblCapTime.Text = $"{(DateTime.Now - StartTime).TotalMilliseconds}ms";
                                onlinePictureBox.Image = bitmap;
                            }
                            else
                            {
                                this.lblCapTime.Text = "-1ms";
                            }
                        }));
                    }
                }
                else
                {
                    // 如果StartSingleGrab失败,回退到传统的GetImageWithSoftTrigger
                    camera.GetImageWithSoftTrigger(out bitmap);
                    this.BeginInvoke(new Action(() =>
                    {
                        if (bitmap != null)
                        {
                            this.lblCapTime.Text = $"{(DateTime.Now - StartTime).TotalMilliseconds}ms";
                            onlinePictureBox.Image = bitmap;
                        }
                        else
                        {
                            this.lblCapTime.Text = "-1ms";
                        }
                    }));
                }
            });
        }
@@ -453,12 +578,12 @@
            total.Clear();
            // 尝试将输入字符串转换为枚举值
            if (Enum.TryParse(cmbBrand.Text, true, out CameraBrand brand))
            {
                camera.StopGrabbing();
                camera.StartWith_HardTriggerModel();
            }
            // 停止当前采集
            camera.StopGrabbing();
            // 调用基类接口的连续采集方法
            // LBCamera会调用StartContinuousGrab方法,其他相机使用原有的StartWith_HardTriggerModel
            camera.StartContinuousGrab();
            startGrabtime = DateTime.Now;
@@ -473,18 +598,15 @@
            total.Clear();
            // 尝试将输入字符串转换为枚举值
            if (Enum.TryParse(cmbBrand.Text, true, out CameraBrand brand))
            {
                Task.Factory.StartNew(() =>
                {
                    camera.StopGrabbing();
                    camera.StartWith_SoftTriggerModel();
            // 停止当前采集
            camera.StopGrabbing();
                });
            }
            // 调用基类接口的连续采集方法
            // LBCamera会调用StartContinuousGrab方法,其他相机使用原有的StartWith_SoftTriggerModel
            camera.StartContinuousGrab();
            startGrabtime = DateTime.Now;
            cmbSN.Enabled = false;
            cmbBrand.Enabled = false;
        }
@@ -655,6 +777,10 @@
        private void CameraForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            onlinePictureBox.Visible = true;
            this.panel_Picture.Controls.Clear();
            this.panel_Picture.Controls.Add(onlinePictureBox);
            this.onlinePictureBox.Image = null;
            if (camera != null)
            {
@@ -667,7 +793,12 @@
                else
                    camera.SetTriggerMode(TriggerMode.On, actualSource);
                camera.StartGrabbing();
                // LBCamera在StartGrabbing时会直接开启激光和采集,因此关闭窗口时不应自动重启采集
                // 其他相机(如2D相机)通常需要保持Grabbing状态以接收触发
                if (camera.Brand != CameraBrand.LBCamera)
                {
                    camera.StartGrabbing();
                }
            }
            //路径为空说明为测试模式,需要释放相机