From 86e3fd80120538ecd26928ec34faa84c5fea230f Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 16:45:54 +0800 Subject: [PATCH 01/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8DCamera.Designer.cs?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=ADpauseImageUpdateToolStripMenuItem?= =?UTF-8?q?=E5=92=8CtoolStripSeparator1=E6=8E=A7=E4=BB=B6=E6=9C=AA?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Toprie/Toprie/Camera.Designer.cs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs index 0e05154..8837758 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs @@ -35,6 +35,8 @@ namespace JoyD.Windows.CS.Toprie this.ironGrayToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.redHotToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.rainbow2ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.pauseImageUpdateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.imageBox)).BeginInit(); this.contextMenuStrip1.SuspendLayout(); this.SuspendLayout(); @@ -54,9 +56,11 @@ namespace JoyD.Windows.CS.Toprie // this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.imageModeToolStripMenuItem, - this.colorModeToolStripMenuItem}); + this.colorModeToolStripMenuItem, + this.toolStripSeparator1, + this.pauseImageUpdateToolStripMenuItem}); this.contextMenuStrip1.Name = "contextMenuStrip1"; - this.contextMenuStrip1.Size = new System.Drawing.Size(161, 74); + this.contextMenuStrip1.Size = new System.Drawing.Size(161, 100); // // imageModeToolStripMenuItem // @@ -92,6 +96,18 @@ namespace JoyD.Windows.CS.Toprie this.ironGrayToolStripMenuItem, this.redHotToolStripMenuItem, this.rainbow2ToolStripMenuItem}); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(157, 6); + // + // pauseImageUpdateToolStripMenuItem + // + this.pauseImageUpdateToolStripMenuItem.Name = "pauseImageUpdateToolStripMenuItem"; + this.pauseImageUpdateToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; + this.pauseImageUpdateToolStripMenuItem.Click += new System.EventHandler(this.pauseImageUpdateToolStripMenuItem_Click); this.colorModeToolStripMenuItem.Name = "colorModeToolStripMenuItem"; this.colorModeToolStripMenuItem.Size = new System.Drawing.Size(160, 22); this.colorModeToolStripMenuItem.Text = "色彩模式"; @@ -172,6 +188,8 @@ namespace JoyD.Windows.CS.Toprie private System.Windows.Forms.PictureBox imageBox; private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem pauseImageUpdateToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; private System.Windows.Forms.ToolStripMenuItem colorModeToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem whiteHotToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem blackHotToolStripMenuItem; From a0a440045699aa7aead46e95e34e0822d17fe42c Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 16:50:16 +0800 Subject: [PATCH 02/64] =?UTF-8?q?=E7=A7=BB=E9=99=A4DeviceManager.cs?= =?UTF-8?q?=E4=B8=AD=E6=9C=AA=E4=BD=BF=E7=94=A8=E7=9A=84=5FconnectionCheck?= =?UTF-8?q?Interval=E5=AD=97=E6=AE=B5=EF=BC=8C=E4=BF=AE=E5=A4=8DCS0414?= =?UTF-8?q?=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index 2f31099..665256b 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -190,7 +190,6 @@ namespace JoyD.Windows.CS.Toprie private System.Threading.Timer _reconnectTimer; // 重连间隔(毫秒) private int _reconnectInterval = 2000; - private int _connectionCheckInterval = 5000; // 重连尝试次数 private int _reconnectAttempts = 0; // 最大重连尝试次数 From 1fb1f6c836e51b3ce27d4716144b5664c86cccfe Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 16:52:16 +0800 Subject: [PATCH 03/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E6=9C=AA=E4=BD=BF=E7=94=A8=E5=AD=97=E6=AE=B5=E5=92=8C=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E7=9A=84=E7=BC=96=E8=AF=91=E5=99=A8=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs | 10 +--------- Windows/CS/Framework4.0/Toprie/Toprie/V8.cs | 2 -- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index 665256b..cc8dec9 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -190,8 +190,6 @@ namespace JoyD.Windows.CS.Toprie private System.Threading.Timer _reconnectTimer; // 重连间隔(毫秒) private int _reconnectInterval = 2000; - // 重连尝试次数 - private int _reconnectAttempts = 0; // 最大重连尝试次数 public static int MaxReconnectAttempts = 5; // 连接检查定时器 @@ -210,12 +208,7 @@ namespace JoyD.Windows.CS.Toprie private const int DataReceivedTimeout = 15000; // 15秒内未收到数据则认为连接可能断开 // TCP客户端 // 该变量已在文件上方定义,删除重复实现 - // 网络流 - private NetworkStream _imageNetworkStream; - // 图像接收任务 - private Task _imageReceivingTask; - // 取消令牌源 - private CancellationTokenSource _imageReceivingCts; + // 停止请求事件 private ManualResetEvent _stopRequested = new ManualResetEvent(false); // 缓冲区 @@ -1597,7 +1590,6 @@ namespace JoyD.Windows.CS.Toprie } Log("开始使用HTTP方式接收图像数据"); - bool existed = false; try { // 确保之前的连接已关闭 diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs index 01d0bdc..2c01041 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs @@ -130,14 +130,12 @@ namespace JoyD.Windows.CS.Toprie // 私有字段 private string deviceIp; private Socket socket; - private bool isConnected; private static bool isSdkInitialized = false; private static Dictionary deviceInstances = new Dictionary(); public V8(string ip) { deviceIp = ip; - isConnected = false; } ~V8() From 5b4f2bea6273cd5ea12e22969a7989c08fb9222c Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 16:54:10 +0800 Subject: [PATCH 04/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8DDeviceManager.cs?= =?UTF-8?q?=E4=B8=AD=E7=BC=BA=E5=B0=91=5FreconnectAttempts=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index cc8dec9..46604e4 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -190,6 +190,8 @@ namespace JoyD.Windows.CS.Toprie private System.Threading.Timer _reconnectTimer; // 重连间隔(毫秒) private int _reconnectInterval = 2000; + // 重连尝试次数 + private int _reconnectAttempts = 0; // 最大重连尝试次数 public static int MaxReconnectAttempts = 5; // 连接检查定时器 From 5772b499d5954bba9f19a1aff328d6c9154e117e Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 16:55:27 +0800 Subject: [PATCH 05/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8DV8.cs=E4=B8=AD=E7=BC=BA?= =?UTF-8?q?=E5=B0=91isConnected=E5=AD=97=E6=AE=B5=E7=9A=84=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/V8.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs index 2c01041..a35e213 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs @@ -130,6 +130,7 @@ namespace JoyD.Windows.CS.Toprie // 私有字段 private string deviceIp; private Socket socket; + private bool isConnected = false; private static bool isSdkInitialized = false; private static Dictionary deviceInstances = new Dictionary(); From 80ae0c4023d185c4c6f22579f66a6cfa5e924b7d Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 16:57:35 +0800 Subject: [PATCH 06/64] =?UTF-8?q?=E5=88=A0=E9=99=A4DeviceManager=E5=92=8CV?= =?UTF-8?q?8=E7=B1=BB=E4=B8=AD=E6=9C=AA=E4=BD=BF=E7=94=A8=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=8C=E6=B6=88=E9=99=A4CS0414=E8=AD=A6?= =?UTF-8?q?=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs | 3 +-- Windows/CS/Framework4.0/Toprie/Toprie/V8.cs | 10 ++++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index 46604e4..31cb5fb 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -191,7 +191,7 @@ namespace JoyD.Windows.CS.Toprie // 重连间隔(毫秒) private int _reconnectInterval = 2000; // 重连尝试次数 - private int _reconnectAttempts = 0; + // 最大重连尝试次数 public static int MaxReconnectAttempts = 5; // 连接检查定时器 @@ -3188,7 +3188,6 @@ namespace JoyD.Windows.CS.Toprie if (result) { _isConnected = true; - _reconnectAttempts = 0; // 启动心跳检测和连接检查 StartHeartbeat(); diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs index a35e213..2a7c398 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs @@ -129,8 +129,7 @@ namespace JoyD.Windows.CS.Toprie // 私有字段 private string deviceIp; - private Socket socket; - private bool isConnected = false; + private Socket socket = null; private static bool isSdkInitialized = false; private static Dictionary deviceInstances = new Dictionary(); @@ -157,10 +156,9 @@ namespace JoyD.Windows.CS.Toprie if (socket != null) { socket.Close(); - socket = null; - } - isConnected = false; - Console.WriteLine("UDP通信状态已重置"); + socket = null; + } + Console.WriteLine("UDP通信状态已重置"); } catch (Exception ex) { From 931381d36a20365fd84aa25565078afd79bb0c21 Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 16:59:35 +0800 Subject: [PATCH 07/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8DCamera.cs=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E5=91=BD=E5=90=8D=E8=A7=84=E5=88=99=E5=86=B2=E7=AA=81?= =?UTF-8?q?=EF=BC=8C=E5=B0=86=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E5=90=8D=E4=BB=8EcamelCase=E6=94=B9=E4=B8=BAPascalCas?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Toprie/Toprie/Camera.Designer.cs | 22 ++--- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 91 +++++++++++++++---- 2 files changed, 84 insertions(+), 29 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs index 8837758..a95b8be 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs @@ -76,14 +76,14 @@ namespace JoyD.Windows.CS.Toprie this.thermalModeToolStripMenuItem.Name = "thermalModeToolStripMenuItem"; this.thermalModeToolStripMenuItem.Size = new System.Drawing.Size(152, 22); this.thermalModeToolStripMenuItem.Text = "红外模式"; - this.thermalModeToolStripMenuItem.Click += new System.EventHandler(this.thermalModeToolStripMenuItem_Click); + this.thermalModeToolStripMenuItem.Click += new System.EventHandler(this.ThermalModeToolStripMenuItem_Click); // // visibleModeToolStripMenuItem // this.visibleModeToolStripMenuItem.Name = "visibleModeToolStripMenuItem"; this.visibleModeToolStripMenuItem.Size = new System.Drawing.Size(152, 22); this.visibleModeToolStripMenuItem.Text = "自然模式"; - this.visibleModeToolStripMenuItem.Click += new System.EventHandler(this.visibleModeToolStripMenuItem_Click); + this.visibleModeToolStripMenuItem.Click += new System.EventHandler(this.VisibleModeToolStripMenuItem_Click); // // colorModeToolStripMenuItem // @@ -107,7 +107,7 @@ namespace JoyD.Windows.CS.Toprie this.pauseImageUpdateToolStripMenuItem.Name = "pauseImageUpdateToolStripMenuItem"; this.pauseImageUpdateToolStripMenuItem.Size = new System.Drawing.Size(160, 22); this.pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; - this.pauseImageUpdateToolStripMenuItem.Click += new System.EventHandler(this.pauseImageUpdateToolStripMenuItem_Click); + this.pauseImageUpdateToolStripMenuItem.Click += new System.EventHandler(this.PauseImageUpdateToolStripMenuItem_Click); this.colorModeToolStripMenuItem.Name = "colorModeToolStripMenuItem"; this.colorModeToolStripMenuItem.Size = new System.Drawing.Size(160, 22); this.colorModeToolStripMenuItem.Text = "色彩模式"; @@ -117,56 +117,56 @@ namespace JoyD.Windows.CS.Toprie this.rainbowToolStripMenuItem.Name = "rainbowToolStripMenuItem"; this.rainbowToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.rainbowToolStripMenuItem.Text = "彩虹"; - this.rainbowToolStripMenuItem.Click += new System.EventHandler(this.rainbowToolStripMenuItem_Click); + this.rainbowToolStripMenuItem.Click += new System.EventHandler(this.RainbowToolStripMenuItem_Click); // // ironRedToolStripMenuItem // this.ironRedToolStripMenuItem.Name = "ironRedToolStripMenuItem"; this.ironRedToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.ironRedToolStripMenuItem.Text = "铁红"; - this.ironRedToolStripMenuItem.Click += new System.EventHandler(this.ironRedToolStripMenuItem_Click); + this.ironRedToolStripMenuItem.Click += new System.EventHandler(this.IronRedToolStripMenuItem_Click); // // lavaToolStripMenuItem // this.lavaToolStripMenuItem.Name = "lavaToolStripMenuItem"; this.lavaToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.lavaToolStripMenuItem.Text = "熔岩"; - this.lavaToolStripMenuItem.Click += new System.EventHandler(this.lavaToolStripMenuItem_Click); + this.lavaToolStripMenuItem.Click += new System.EventHandler(this.LavaToolStripMenuItem_Click); // // ironGrayToolStripMenuItem // this.ironGrayToolStripMenuItem.Name = "ironGrayToolStripMenuItem"; this.ironGrayToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.ironGrayToolStripMenuItem.Text = "铁灰"; - this.ironGrayToolStripMenuItem.Click += new System.EventHandler(this.ironGrayToolStripMenuItem_Click); + this.ironGrayToolStripMenuItem.Click += new System.EventHandler(this.IronGrayToolStripMenuItem_Click); // // redHotToolStripMenuItem // this.redHotToolStripMenuItem.Name = "redHotToolStripMenuItem"; this.redHotToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.redHotToolStripMenuItem.Text = "红热"; - this.redHotToolStripMenuItem.Click += new System.EventHandler(this.redHotToolStripMenuItem_Click); + this.redHotToolStripMenuItem.Click += new System.EventHandler(this.RedHotToolStripMenuItem_Click); // // rainbow2ToolStripMenuItem // this.rainbow2ToolStripMenuItem.Name = "rainbow2ToolStripMenuItem"; this.rainbow2ToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.rainbow2ToolStripMenuItem.Text = "彩虹2"; - this.rainbow2ToolStripMenuItem.Click += new System.EventHandler(this.rainbow2ToolStripMenuItem_Click); + this.rainbow2ToolStripMenuItem.Click += new System.EventHandler(this.Rainbow2ToolStripMenuItem_Click); // // whiteHotToolStripMenuItem // this.whiteHotToolStripMenuItem.Name = "whiteHotToolStripMenuItem"; this.whiteHotToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.whiteHotToolStripMenuItem.Text = "白热"; - this.whiteHotToolStripMenuItem.Click += new System.EventHandler(this.whiteHotToolStripMenuItem_Click); + this.whiteHotToolStripMenuItem.Click += new System.EventHandler(this.WhiteHotToolStripMenuItem_Click); // // blackHotToolStripMenuItem // this.blackHotToolStripMenuItem.Name = "blackHotToolStripMenuItem"; this.blackHotToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.blackHotToolStripMenuItem.Text = "黑热"; - this.blackHotToolStripMenuItem.Click += new System.EventHandler(this.blackHotToolStripMenuItem_Click); + this.blackHotToolStripMenuItem.Click += new System.EventHandler(this.BlackHotToolStripMenuItem_Click); // // 已移除蓝红菜单项(不在SDK的8种标准色板中) // diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index cfe5736..5150128 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -19,6 +19,9 @@ namespace JoyD.Windows.CS.Toprie // 是否正在接收图像 private bool _isReceivingImage = false; + // 是否暂停图像更新 + private bool _isImageUpdatePaused = false; + // 项目路径,用于数据文件的存取 private string _projectPath = ""; @@ -30,18 +33,18 @@ namespace JoyD.Windows.CS.Toprie [DefaultValue("")] public string ProjectPath { - get { return _projectPath; } + get { return _projectPath; } set { // 只有当值发生变化时才进行同步 if (_projectPath != value) - { - _projectPath = value; + { + _projectPath = value; // 如果DeviceManager已经初始化,则同步更新其ProjectPath属性 - if (_deviceManager != null) - { - _deviceManager.ProjectPath = _projectPath; - } + if (_deviceManager != null) + { + _deviceManager.ProjectPath = _projectPath; + } } } } @@ -57,6 +60,44 @@ namespace JoyD.Windows.CS.Toprie DeviceManager.IsDesignMode = DesignMode; Console.WriteLine($"相机控件设计模式状态已更新: {DesignMode}"); } + + /// + /// 暂停/恢复图像更新菜单项点击事件处理 + /// + private void PauseImageUpdateToolStripMenuItem_Click(object sender, EventArgs e) + { + if (DesignMode) return; + + try + { + // 切换暂停状态 + _isImageUpdatePaused = !_isImageUpdatePaused; + + if (_isImageUpdatePaused) + { + pauseImageUpdateToolStripMenuItem.Text = "恢复图像更新"; + pauseImageUpdateToolStripMenuItem.Checked = true; + Console.WriteLine("图像更新已暂停"); + } + else + { + pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; + pauseImageUpdateToolStripMenuItem.Checked = false; + Console.WriteLine("图像更新已恢复"); + + // 恢复时,立即停止并重新开始图像接收,确保获取最新图像 + if (_isReceivingImage && _deviceManager != null) + { + _deviceManager.StopImageReceiving(); + _deviceManager.StartImageReceiving(); + } + } + } + catch (Exception ex) + { + Console.WriteLine($"处理暂停/恢复图像更新时出错: {ex.Message}"); + } + } public Camera() { @@ -287,6 +328,9 @@ namespace JoyD.Windows.CS.Toprie /// private void DeviceManager_ImageReceived(object sender, ImageReceivedEventArgs e) { + // 如果图像更新已暂停,则不更新UI + if (_isImageUpdatePaused) + return; if (DesignMode) return; Image image = null; try @@ -1018,6 +1062,17 @@ namespace JoyD.Windows.CS.Toprie /// private void ContextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e) { + // 更新暂停菜单项的文本和状态 + if (_isImageUpdatePaused) + { + pauseImageUpdateToolStripMenuItem.Text = "恢复图像更新"; + pauseImageUpdateToolStripMenuItem.Checked = true; + } + else + { + pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; + pauseImageUpdateToolStripMenuItem.Checked = false; + } if (DesignMode) return; try { @@ -1047,7 +1102,7 @@ namespace JoyD.Windows.CS.Toprie rainbow2ToolStripMenuItem.Checked = false; // 尝试获取当前色彩模式并更新对应菜单项的选中状态 - if (_deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected) + if (!_isImageUpdatePaused && _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected) { try { @@ -1113,7 +1168,7 @@ namespace JoyD.Windows.CS.Toprie /// /// 白热色彩模式 /// - private void whiteHotToolStripMenuItem_Click(object sender, EventArgs e) + private void WhiteHotToolStripMenuItem_Click(object sender, EventArgs e) { try { @@ -1132,7 +1187,7 @@ namespace JoyD.Windows.CS.Toprie /// /// 黑热色彩模式 /// - private void blackHotToolStripMenuItem_Click(object sender, EventArgs e) + private void BlackHotToolStripMenuItem_Click(object sender, EventArgs e) { try { @@ -1151,7 +1206,7 @@ namespace JoyD.Windows.CS.Toprie /// /// 铁红色彩模式 /// - private void ironRedToolStripMenuItem_Click(object sender, EventArgs e) + private void IronRedToolStripMenuItem_Click(object sender, EventArgs e) { try { @@ -1170,7 +1225,7 @@ namespace JoyD.Windows.CS.Toprie /// /// 熔岩色彩模式 /// - private void lavaToolStripMenuItem_Click(object sender, EventArgs e) + private void LavaToolStripMenuItem_Click(object sender, EventArgs e) { try { @@ -1189,7 +1244,7 @@ namespace JoyD.Windows.CS.Toprie /// /// 彩虹色彩模式 /// - private void rainbowToolStripMenuItem_Click(object sender, EventArgs e) + private void RainbowToolStripMenuItem_Click(object sender, EventArgs e) { try { @@ -1208,7 +1263,7 @@ namespace JoyD.Windows.CS.Toprie /// /// 铁灰色彩模式 /// - private void ironGrayToolStripMenuItem_Click(object sender, EventArgs e) + private void IronGrayToolStripMenuItem_Click(object sender, EventArgs e) { try { @@ -1227,7 +1282,7 @@ namespace JoyD.Windows.CS.Toprie /// /// 红热色彩模式 /// - private void redHotToolStripMenuItem_Click(object sender, EventArgs e) + private void RedHotToolStripMenuItem_Click(object sender, EventArgs e) { try { @@ -1246,7 +1301,7 @@ namespace JoyD.Windows.CS.Toprie /// /// 彩虹2色彩模式 /// - private void rainbow2ToolStripMenuItem_Click(object sender, EventArgs e) + private void Rainbow2ToolStripMenuItem_Click(object sender, EventArgs e) { try { @@ -1269,7 +1324,7 @@ namespace JoyD.Windows.CS.Toprie /// /// 红外模式 /// - private void thermalModeToolStripMenuItem_Click(object sender, EventArgs e) + private void ThermalModeToolStripMenuItem_Click(object sender, EventArgs e) { try { @@ -1282,7 +1337,7 @@ namespace JoyD.Windows.CS.Toprie } } - private void visibleModeToolStripMenuItem_Click(object sender, EventArgs e) + private void VisibleModeToolStripMenuItem_Click(object sender, EventArgs e) { try { From 236411ecaea1d770d873331517a5f7c17e63dff8 Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 17:01:36 +0800 Subject: [PATCH 08/64] =?UTF-8?q?=E4=B8=BADeviceManager=E5=92=8CV8?= =?UTF-8?q?=E7=B1=BB=E4=B8=AD=E7=AC=A6=E5=90=88=E6=9D=A1=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=B7=BB=E5=8A=A0readonly=E5=85=B3=E9=94=AE?= =?UTF-8?q?=E5=AD=97=EF=BC=8C=E8=A7=A3=E5=86=B3IDE0044=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Framework4.0/Toprie/Toprie/DeviceManager.cs | 16 ++++++++-------- Windows/CS/Framework4.0/Toprie/Toprie/V8.cs | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index 31cb5fb..d51ce5f 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -169,9 +169,9 @@ namespace JoyD.Windows.CS.Toprie // 当前设备ID private int _currentDeviceId = -1; // 默认设备IP - private string _deviceIp = "192.168.100.2"; + private readonly string _deviceIp = "192.168.100.2"; // 设备端口 - private int _devicePort = 8080; + private readonly int _devicePort = 8080; // 设备连接状态 private ConnectionStatus _connectionStatus = ConnectionStatus.Disconnected; // 是否已初始化 @@ -179,7 +179,7 @@ namespace JoyD.Windows.CS.Toprie // 是否已释放 private bool _isDisposed = false; // 图像模式 - private ImageMode _currentImageMode = ImageMode.Infrared; + private readonly ImageMode _currentImageMode = ImageMode.Infrared; // 当前色彩模式 private PaletteType _currentPaletteType = PaletteType.WhiteHot; // 当前视频模式 @@ -195,15 +195,15 @@ namespace JoyD.Windows.CS.Toprie // 最大重连尝试次数 public static int MaxReconnectAttempts = 5; // 连接检查定时器 - private System.Threading.Timer _connectionCheckTimer; + private readonly System.Threading.Timer _connectionCheckTimer; // 心跳定时器 - private System.Threading.Timer _heartbeatTimer; + private readonly System.Threading.Timer _heartbeatTimer; // 连接超时时间(毫秒) private const int ConnectionTimeout = 5000; // 连接检查间隔(毫秒) private const int ConnectionCheckInterval = 5000; // 心跳间隔(毫秒) - private int _heartbeatInterval = 5000; + private readonly int _heartbeatInterval = 5000; // 最后接收数据时间戳 private DateTime _lastDataReceivedTime = DateTime.MinValue; // 数据接收超时时间(毫秒) @@ -212,7 +212,7 @@ namespace JoyD.Windows.CS.Toprie // 该变量已在文件上方定义,删除重复实现 // 停止请求事件 - private ManualResetEvent _stopRequested = new ManualResetEvent(false); + private readonly ManualResetEvent _stopRequested = new ManualResetEvent(false); // 缓冲区 private byte[] _imageBuffer = new byte[4096]; // 图像数据累积缓冲区 @@ -220,7 +220,7 @@ namespace JoyD.Windows.CS.Toprie // 多部分请求边界 private string _multipartBoundary = string.Empty; // 锁对象 - private object _lockObject = new object(); + private readonly object _lockObject = new object(); // 是否启用自动重连 private bool _isAutoReconnectEnabled = true; // 最大重连次数 diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs index 2a7c398..3548411 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs @@ -131,7 +131,7 @@ namespace JoyD.Windows.CS.Toprie private string deviceIp; private Socket socket = null; private static bool isSdkInitialized = false; - private static Dictionary deviceInstances = new Dictionary(); + private static readonly Dictionary deviceInstances = new Dictionary(); public V8(string ip) { From f0e894f9d5506fd40e8768dfeeedd54df19a6231 Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 17:05:34 +0800 Subject: [PATCH 09/64] =?UTF-8?q?=E7=A7=BB=E9=99=A4DeviceManager=E4=B8=AD?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E7=BC=96=E8=AF=91=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E5=8F=AA=E8=AF=BB=E5=AD=97=E6=AE=B5=EF=BC=8C=E4=BF=9D=E7=95=99?= =?UTF-8?q?=5FlockObject=E5=92=8CdeviceInstances=E7=9A=84readonly=E5=85=B3?= =?UTF-8?q?=E9=94=AE=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/DeviceManager.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index d51ce5f..43da737 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -169,9 +169,9 @@ namespace JoyD.Windows.CS.Toprie // 当前设备ID private int _currentDeviceId = -1; // 默认设备IP - private readonly string _deviceIp = "192.168.100.2"; + private string _deviceIp = "192.168.100.2"; // 设备端口 - private readonly int _devicePort = 8080; + private int _devicePort = 8080; // 设备连接状态 private ConnectionStatus _connectionStatus = ConnectionStatus.Disconnected; // 是否已初始化 @@ -179,7 +179,7 @@ namespace JoyD.Windows.CS.Toprie // 是否已释放 private bool _isDisposed = false; // 图像模式 - private readonly ImageMode _currentImageMode = ImageMode.Infrared; + private ImageMode _currentImageMode = ImageMode.Infrared; // 当前色彩模式 private PaletteType _currentPaletteType = PaletteType.WhiteHot; // 当前视频模式 @@ -195,15 +195,15 @@ namespace JoyD.Windows.CS.Toprie // 最大重连尝试次数 public static int MaxReconnectAttempts = 5; // 连接检查定时器 - private readonly System.Threading.Timer _connectionCheckTimer; + private System.Threading.Timer _connectionCheckTimer; // 心跳定时器 - private readonly System.Threading.Timer _heartbeatTimer; + private System.Threading.Timer _heartbeatTimer; // 连接超时时间(毫秒) private const int ConnectionTimeout = 5000; // 连接检查间隔(毫秒) private const int ConnectionCheckInterval = 5000; // 心跳间隔(毫秒) - private readonly int _heartbeatInterval = 5000; + private int _heartbeatInterval = 5000; // 最后接收数据时间戳 private DateTime _lastDataReceivedTime = DateTime.MinValue; // 数据接收超时时间(毫秒) @@ -212,7 +212,7 @@ namespace JoyD.Windows.CS.Toprie // 该变量已在文件上方定义,删除重复实现 // 停止请求事件 - private readonly ManualResetEvent _stopRequested = new ManualResetEvent(false); + private ManualResetEvent _stopRequested = new ManualResetEvent(false); // 缓冲区 private byte[] _imageBuffer = new byte[4096]; // 图像数据累积缓冲区 From af4cbb58958ab281050691712ef73cfce9af511c Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 17:10:22 +0800 Subject: [PATCH 10/64] =?UTF-8?q?=E5=B0=86DeviceManager=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=5FtargetDeviceId=E5=AD=97=E6=AE=B5=E8=AE=BE=E4=B8=BA=E5=8F=AA?= =?UTF-8?q?=E8=AF=BB=EF=BC=8C=E8=A7=A3=E5=86=B3IDE0044=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index 43da737..b703c38 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -165,7 +165,7 @@ namespace JoyD.Windows.CS.Toprie private List _deviceList = new List(); // 目标设备ID,用于指定ID连接 - private int _targetDeviceId = -1; + private readonly int _targetDeviceId = -1; // 当前设备ID private int _currentDeviceId = -1; // 默认设备IP From 6b774ad5802355c025e4ea21badc693bb6e0a831 Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 17:14:12 +0800 Subject: [PATCH 11/64] =?UTF-8?q?=E5=B0=86DeviceManager=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=5FimageBuffer=E3=80=81=5FimageDataAccumulator=E5=92=8C=5Fmulti?= =?UTF-8?q?partBoundary=E5=AD=97=E6=AE=B5=E8=AE=BE=E4=B8=BA=E5=8F=AA?= =?UTF-8?q?=E8=AF=BB=EF=BC=8C=E8=A7=A3=E5=86=B3IDE0044=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index b703c38..e02bcb4 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -214,11 +214,11 @@ namespace JoyD.Windows.CS.Toprie // 停止请求事件 private ManualResetEvent _stopRequested = new ManualResetEvent(false); // 缓冲区 - private byte[] _imageBuffer = new byte[4096]; + private readonly byte[] _imageBuffer = new byte[4096]; // 图像数据累积缓冲区 - private byte[] _imageDataAccumulator = new byte[0]; + private readonly byte[] _imageDataAccumulator = new byte[0]; // 多部分请求边界 - private string _multipartBoundary = string.Empty; + private readonly string _multipartBoundary = string.Empty; // 锁对象 private readonly object _lockObject = new object(); // 是否启用自动重连 From b1c8ee58d1871e266512acb4183ef5c04534efd9 Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 17:19:58 +0800 Subject: [PATCH 12/64] =?UTF-8?q?=E5=B0=86DeviceManager=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=5FautoReconnectEnabled=E5=92=8C=5FconnectTimeout=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E8=AE=BE=E4=B8=BA=E5=8F=AA=E8=AF=BB=EF=BC=8C=E8=A7=A3?= =?UTF-8?q?=E5=86=B3IDE0044=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index e02bcb4..00b1af8 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -185,7 +185,7 @@ namespace JoyD.Windows.CS.Toprie // 当前视频模式 private VideoMode _currentVideoMode = VideoMode.Infrared; // 默认红外模式 // 自动重连是否启用 - private bool _autoReconnectEnabled = true; + private readonly bool _autoReconnectEnabled = true; // 自动重连定时器 private System.Threading.Timer _reconnectTimer; // 重连间隔(毫秒) @@ -228,7 +228,7 @@ namespace JoyD.Windows.CS.Toprie // 是否已连接 private bool _isConnected = false; // 连接超时设置 - private int _connectTimeout = 5000; + private readonly int _connectTimeout = 5000; // 当前重连尝试次数 private int _currentReconnectAttempt = 0; // 连接取消令牌源 From 860f78815cf01748a3f35414627220f3d38a2680 Mon Sep 17 00:00:00 2001 From: zqm Date: Wed, 29 Oct 2025 17:24:53 +0800 Subject: [PATCH 13/64] =?UTF-8?q?=E5=B0=86V8=E4=B8=AD=E7=9A=84deviceIp?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E8=AE=BE=E4=B8=BA=E5=8F=AA=E8=AF=BB=EF=BC=8C?= =?UTF-8?q?=E8=A7=A3=E5=86=B3IDE0044=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/V8.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs index 3548411..294c5e1 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs @@ -128,7 +128,7 @@ namespace JoyD.Windows.CS.Toprie } // 私有字段 - private string deviceIp; + private readonly string deviceIp; private Socket socket = null; private static bool isSdkInitialized = false; private static readonly Dictionary deviceInstances = new Dictionary(); From b944069565fed877a7bef97aa9a76c6600910a3c Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 08:27:33 +0800 Subject: [PATCH 14/64] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=9A=82=E5=81=9C?= =?UTF-8?q?=E5=9B=BE=E5=83=8F=E6=9B=B4=E6=96=B0=E8=8F=9C=E5=8D=95=E9=A1=B9?= =?UTF-8?q?=E7=9A=84=E5=8B=BE=E9=80=89=E7=8A=B6=E6=80=81=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 5150128..234cad0 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -76,13 +76,11 @@ namespace JoyD.Windows.CS.Toprie if (_isImageUpdatePaused) { pauseImageUpdateToolStripMenuItem.Text = "恢复图像更新"; - pauseImageUpdateToolStripMenuItem.Checked = true; Console.WriteLine("图像更新已暂停"); } else { pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; - pauseImageUpdateToolStripMenuItem.Checked = false; Console.WriteLine("图像更新已恢复"); // 恢复时,立即停止并重新开始图像接收,确保获取最新图像 From a596f78dc8384f08307c68e86d158566eb215f5a Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 08:29:55 +0800 Subject: [PATCH 15/64] =?UTF-8?q?=E7=A7=BB=E9=99=A4ContextMenuStrip1=5FOpe?= =?UTF-8?q?ning=E6=96=B9=E6=B3=95=E4=B8=AD=E8=AE=BE=E7=BD=AE=E6=9A=82?= =?UTF-8?q?=E5=81=9C=E5=9B=BE=E5=83=8F=E6=9B=B4=E6=96=B0=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E9=A1=B9=E5=8B=BE=E9=80=89=E7=8A=B6=E6=80=81=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 234cad0..5a5d3e8 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -1064,12 +1064,10 @@ namespace JoyD.Windows.CS.Toprie if (_isImageUpdatePaused) { pauseImageUpdateToolStripMenuItem.Text = "恢复图像更新"; - pauseImageUpdateToolStripMenuItem.Checked = true; } else { pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; - pauseImageUpdateToolStripMenuItem.Checked = false; } if (DesignMode) return; try From 33e5baaaf597553c879e9daf1792916c7721cb51 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 08:34:10 +0800 Subject: [PATCH 16/64] =?UTF-8?q?=E5=9C=A8Camera=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E4=B8=AD=E6=B7=BB=E5=8A=A0maskImageBox=E4=BD=9C=E4=B8=BA?= =?UTF-8?q?=E9=81=AE=E7=BD=A9=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Toprie/Toprie/Camera.Designer.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs index a95b8be..d4de63f 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs @@ -17,6 +17,7 @@ namespace JoyD.Windows.CS.Toprie { this.components = new System.ComponentModel.Container(); this.imageBox = new System.Windows.Forms.PictureBox(); + this.maskImageBox = new System.Windows.Forms.PictureBox(); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.imageModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.thermalModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -52,6 +53,18 @@ namespace JoyD.Windows.CS.Toprie this.imageBox.TabIndex = 0; this.imageBox.TabStop = false; // + // maskImageBox + // + this.maskImageBox.ContextMenuStrip = this.contextMenuStrip1; + this.maskImageBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.maskImageBox.Location = new System.Drawing.Point(0, 0); + this.maskImageBox.Name = "maskImageBox"; + this.maskImageBox.Size = new System.Drawing.Size(512, 384); + this.maskImageBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.maskImageBox.TabIndex = 1; + this.maskImageBox.TabStop = false; + this.maskImageBox.BackColor = System.Drawing.Color.Transparent; + // // contextMenuStrip1 // this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -175,10 +188,12 @@ namespace JoyD.Windows.CS.Toprie this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.imageBox); + this.Controls.Add(this.maskImageBox); this.Name = "Camera"; this.Size = new System.Drawing.Size(512, 384); this.Load += new System.EventHandler(this.Camera_Load); ((System.ComponentModel.ISupportInitialize)(this.imageBox)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.maskImageBox)).EndInit(); this.contextMenuStrip1.ResumeLayout(false); this.ResumeLayout(false); @@ -187,6 +202,7 @@ namespace JoyD.Windows.CS.Toprie #endregion private System.Windows.Forms.PictureBox imageBox; + private System.Windows.Forms.PictureBox maskImageBox; private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; private System.Windows.Forms.ToolStripMenuItem pauseImageUpdateToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; From 798443424342afb9096c4e2702577d5493013177 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 08:38:16 +0800 Subject: [PATCH 17/64] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=9C=A8=E6=9A=82?= =?UTF-8?q?=E5=81=9C=E7=8A=B6=E6=80=81=E4=B8=8B=E5=9C=A8=E9=81=AE=E7=BD=A9?= =?UTF-8?q?=E5=B1=82=E6=98=BE=E7=A4=BA=E6=9A=82=E5=81=9C=E5=AD=97=E6=A0=B7?= =?UTF-8?q?=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 5a5d3e8..4352580 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -77,11 +77,15 @@ namespace JoyD.Windows.CS.Toprie { pauseImageUpdateToolStripMenuItem.Text = "恢复图像更新"; Console.WriteLine("图像更新已暂停"); + // 显示暂停遮罩 + UpdateMaskDisplay(); } else { pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; Console.WriteLine("图像更新已恢复"); + // 清除暂停遮罩 + UpdateMaskDisplay(); // 恢复时,立即停止并重新开始图像接收,确保获取最新图像 if (_isReceivingImage && _deviceManager != null) @@ -96,6 +100,72 @@ namespace JoyD.Windows.CS.Toprie Console.WriteLine($"处理暂停/恢复图像更新时出错: {ex.Message}"); } } + + /// + /// 更新遮罩层的显示内容 + /// + private void UpdateMaskDisplay() + { + try + { + if (_isImageUpdatePaused) + { + // 创建一个与maskImageBox大小相同的位图 + Bitmap bitmap = new Bitmap(maskImageBox.Width, maskImageBox.Height); + using (Graphics g = Graphics.FromImage(bitmap)) + { + // 设置半透明背景 + using (Brush brush = new SolidBrush(Color.FromArgb(100, Color.Black))) + { + g.FillRectangle(brush, 0, 0, bitmap.Width, bitmap.Height); + } + + // 设置文本样式 + Font font = new Font("微软雅黑", 36, FontStyle.Bold); + Brush textBrush = new SolidBrush(Color.White); + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + // 绘制"暂停"文字 + g.DrawString("暂停", font, textBrush, + new Rectangle(0, 0, bitmap.Width, bitmap.Height), format); + } + + // 在UI线程上更新maskImageBox + if (maskImageBox.InvokeRequired) + { + maskImageBox.Invoke(new Action(() => + { + maskImageBox.Image = bitmap; + })); + } + else + { + maskImageBox.Image = bitmap; + } + } + else + { + // 清除遮罩 + if (maskImageBox.InvokeRequired) + { + maskImageBox.Invoke(new Action(() => + { + maskImageBox.Image = null; + })); + } + else + { + maskImageBox.Image = null; + } + } + } + catch (Exception ex) + { + Console.WriteLine($"更新遮罩显示时出错: {ex.Message}"); + } + } public Camera() { From 8ea1829cf2dc85d6596c505674fe20be5fe8f2c9 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 08:45:23 +0800 Subject: [PATCH 18/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9A=82=E5=81=9C?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E4=B8=8B=E9=81=AE=E7=BD=A9=E5=B1=82=E4=B8=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E6=9A=82=E5=81=9C=E5=AD=97=E6=A0=B7=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 4352580..38d5e73 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -108,62 +108,83 @@ namespace JoyD.Windows.CS.Toprie { try { + Console.WriteLine($"UpdateMaskDisplay called, _isImageUpdatePaused: {_isImageUpdatePaused}, maskImageBox: {maskImageBox}, maskImageBox.Size: {maskImageBox.Width}x{maskImageBox.Height}"); + if (_isImageUpdatePaused) { - // 创建一个与maskImageBox大小相同的位图 - Bitmap bitmap = new Bitmap(maskImageBox.Width, maskImageBox.Height); + // 确保maskImageBox大小有效 + int width = Math.Max(100, maskImageBox.Width); + int height = Math.Max(100, maskImageBox.Height); + + Console.WriteLine($"Creating bitmap with size: {width}x{height}"); + + // 创建一个位图 + Bitmap bitmap = new Bitmap(width, height); using (Graphics g = Graphics.FromImage(bitmap)) { + // 设置高质量绘制 + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + // 设置半透明背景 - using (Brush brush = new SolidBrush(Color.FromArgb(100, Color.Black))) + using (Brush brush = new SolidBrush(Color.FromArgb(150, Color.Black))) { g.FillRectangle(brush, 0, 0, bitmap.Width, bitmap.Height); } // 设置文本样式 - Font font = new Font("微软雅黑", 36, FontStyle.Bold); + Font font = new Font("微软雅黑", 48, FontStyle.Bold); Brush textBrush = new SolidBrush(Color.White); StringFormat format = new StringFormat(); format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; // 绘制"暂停"文字 + Console.WriteLine("Drawing '暂停' text"); g.DrawString("暂停", font, textBrush, new Rectangle(0, 0, bitmap.Width, bitmap.Height), format); } // 在UI线程上更新maskImageBox + Console.WriteLine("Updating maskImageBox image"); if (maskImageBox.InvokeRequired) { maskImageBox.Invoke(new Action(() => { maskImageBox.Image = bitmap; + maskImageBox.Visible = true; + Console.WriteLine("maskImageBox updated via Invoke"); })); } else { maskImageBox.Image = bitmap; + maskImageBox.Visible = true; + Console.WriteLine("maskImageBox updated directly"); } } else { // 清除遮罩 + Console.WriteLine("Clearing maskImageBox image"); if (maskImageBox.InvokeRequired) { maskImageBox.Invoke(new Action(() => { maskImageBox.Image = null; + Console.WriteLine("maskImageBox cleared via Invoke"); })); } else { maskImageBox.Image = null; + Console.WriteLine("maskImageBox cleared directly"); } } } catch (Exception ex) { - Console.WriteLine($"更新遮罩显示时出错: {ex.Message}"); + Console.WriteLine($"更新遮罩显示时出错: {ex.Message}, StackTrace: {ex.StackTrace}"); } } From f9404dd259b74ef8cf93f3d9cce35d1793e75785 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 08:52:53 +0800 Subject: [PATCH 19/64] =?UTF-8?q?=E4=B8=BA=E9=81=AE=E7=BD=A9=E5=B1=82?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=8F=8C=E7=BC=93=E5=86=B2=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=E5=B9=B6=E5=B0=86bitmap=E5=A4=A7=E5=B0=8F=E5=9B=BA=E5=AE=9A?= =?UTF-8?q?=E4=B8=BA512*384?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 86 +++++++++++++------ 1 file changed, 58 insertions(+), 28 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 38d5e73..e397d42 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -108,41 +108,53 @@ namespace JoyD.Windows.CS.Toprie { try { - Console.WriteLine($"UpdateMaskDisplay called, _isImageUpdatePaused: {_isImageUpdatePaused}, maskImageBox: {maskImageBox}, maskImageBox.Size: {maskImageBox.Width}x{maskImageBox.Height}"); + Console.WriteLine($"UpdateMaskDisplay called, _isImageUpdatePaused: {_isImageUpdatePaused}"); if (_isImageUpdatePaused) { - // 确保maskImageBox大小有效 - int width = Math.Max(100, maskImageBox.Width); - int height = Math.Max(100, maskImageBox.Height); + // 使用固定大小512*384,与图像层的src图像大小一致 + const int bitmapWidth = 512; + const int bitmapHeight = 384; - Console.WriteLine($"Creating bitmap with size: {width}x{height}"); + Console.WriteLine($"Creating bitmap with fixed size: {bitmapWidth}x{bitmapHeight} using double buffering"); - // 创建一个位图 - Bitmap bitmap = new Bitmap(width, height); + // 创建一个支持双缓冲的位图 + Bitmap bitmap = new Bitmap(bitmapWidth, bitmapHeight); + + // 使用双缓冲技术绘制 using (Graphics g = Graphics.FromImage(bitmap)) { - // 设置高质量绘制 - g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; - g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; - - // 设置半透明背景 - using (Brush brush = new SolidBrush(Color.FromArgb(150, Color.Black))) + // 创建缓冲区Graphics对象以实现双缓冲 + BufferedGraphicsContext bufferedGraphicsContext = BufferedGraphicsManager.Current; + using (BufferedGraphics bufferedGraphics = bufferedGraphicsContext.Allocate(g, new Rectangle(0, 0, bitmapWidth, bitmapHeight))) { - g.FillRectangle(brush, 0, 0, bitmap.Width, bitmap.Height); + Graphics bufferGraphics = bufferedGraphics.Graphics; + + // 设置高质量绘制 + bufferGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + bufferGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + + // 设置半透明背景 + using (Brush brush = new SolidBrush(Color.FromArgb(150, Color.Black))) + { + bufferGraphics.FillRectangle(brush, 0, 0, bitmapWidth, bitmapHeight); + } + + // 设置文本样式 + Font font = new Font("微软雅黑", 48, FontStyle.Bold); + Brush textBrush = new SolidBrush(Color.White); + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + // 绘制"暂停"文字 + Console.WriteLine("Drawing '暂停' text"); + bufferGraphics.DrawString("暂停", font, textBrush, + new Rectangle(0, 0, bitmapWidth, bitmapHeight), format); + + // 将缓冲区内容绘制到目标位图 + bufferedGraphics.Render(g); } - - // 设置文本样式 - Font font = new Font("微软雅黑", 48, FontStyle.Bold); - Brush textBrush = new SolidBrush(Color.White); - StringFormat format = new StringFormat(); - format.Alignment = StringAlignment.Center; - format.LineAlignment = StringAlignment.Center; - - // 绘制"暂停"文字 - Console.WriteLine("Drawing '暂停' text"); - g.DrawString("暂停", font, textBrush, - new Rectangle(0, 0, bitmap.Width, bitmap.Height), format); } // 在UI线程上更新maskImageBox @@ -151,6 +163,11 @@ namespace JoyD.Windows.CS.Toprie { maskImageBox.Invoke(new Action(() => { + // 先释放之前的图像资源 + if (maskImageBox.Image != null) + { + maskImageBox.Image.Dispose(); + } maskImageBox.Image = bitmap; maskImageBox.Visible = true; Console.WriteLine("maskImageBox updated via Invoke"); @@ -158,6 +175,11 @@ namespace JoyD.Windows.CS.Toprie } else { + // 先释放之前的图像资源 + if (maskImageBox.Image != null) + { + maskImageBox.Image.Dispose(); + } maskImageBox.Image = bitmap; maskImageBox.Visible = true; Console.WriteLine("maskImageBox updated directly"); @@ -171,13 +193,21 @@ namespace JoyD.Windows.CS.Toprie { maskImageBox.Invoke(new Action(() => { - maskImageBox.Image = null; + if (maskImageBox.Image != null) + { + maskImageBox.Image.Dispose(); + maskImageBox.Image = null; + } Console.WriteLine("maskImageBox cleared via Invoke"); })); } else { - maskImageBox.Image = null; + if (maskImageBox.Image != null) + { + maskImageBox.Image.Dispose(); + maskImageBox.Image = null; + } Console.WriteLine("maskImageBox cleared directly"); } } From 902bc197c24e9ac88f4d32863a13bbcceccca987 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 08:56:58 +0800 Subject: [PATCH 20/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9A=82=E5=81=9C?= =?UTF-8?q?=E5=AD=97=E6=A0=B7=E4=B8=8D=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9A=E4=BC=98=E5=8C=96UpdateMaskDisplay=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=B9=B6=E7=A1=AE=E4=BF=9DmaskImageBox=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E6=AD=A3=E7=A1=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Toprie/Toprie/Camera.Designer.cs | 3 + .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 116 ++++++------------ 2 files changed, 43 insertions(+), 76 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs index d4de63f..69bd657 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs @@ -64,6 +64,7 @@ namespace JoyD.Windows.CS.Toprie this.maskImageBox.TabIndex = 1; this.maskImageBox.TabStop = false; this.maskImageBox.BackColor = System.Drawing.Color.Transparent; + this.maskImageBox.Visible = true; // // contextMenuStrip1 // @@ -187,7 +188,9 @@ namespace JoyD.Windows.CS.Toprie // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + // 先添加imageBox基础层 this.Controls.Add(this.imageBox); + // 再添加maskImageBox遮罩层,确保它显示在上面 this.Controls.Add(this.maskImageBox); this.Name = "Camera"; this.Size = new System.Drawing.Size(512, 384); diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index e397d42..c7abc8f 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -110,106 +110,70 @@ namespace JoyD.Windows.CS.Toprie { Console.WriteLine($"UpdateMaskDisplay called, _isImageUpdatePaused: {_isImageUpdatePaused}"); + // 在UI线程上操作 + if (InvokeRequired) + { + Invoke(new Action(UpdateMaskDisplay)); + return; + } + if (_isImageUpdatePaused) { // 使用固定大小512*384,与图像层的src图像大小一致 const int bitmapWidth = 512; const int bitmapHeight = 384; - Console.WriteLine($"Creating bitmap with fixed size: {bitmapWidth}x{bitmapHeight} using double buffering"); + Console.WriteLine($"Creating bitmap with fixed size: {bitmapWidth}x{bitmapHeight}"); - // 创建一个支持双缓冲的位图 + // 创建位图 Bitmap bitmap = new Bitmap(bitmapWidth, bitmapHeight); - // 使用双缓冲技术绘制 + // 直接在bitmap上绘制 using (Graphics g = Graphics.FromImage(bitmap)) { - // 创建缓冲区Graphics对象以实现双缓冲 - BufferedGraphicsContext bufferedGraphicsContext = BufferedGraphicsManager.Current; - using (BufferedGraphics bufferedGraphics = bufferedGraphicsContext.Allocate(g, new Rectangle(0, 0, bitmapWidth, bitmapHeight))) + // 设置高质量绘制 + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + + // 设置半透明背景 + using (Brush brush = new SolidBrush(Color.FromArgb(150, Color.Black))) { - Graphics bufferGraphics = bufferedGraphics.Graphics; - - // 设置高质量绘制 - bufferGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; - bufferGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; - - // 设置半透明背景 - using (Brush brush = new SolidBrush(Color.FromArgb(150, Color.Black))) - { - bufferGraphics.FillRectangle(brush, 0, 0, bitmapWidth, bitmapHeight); - } - - // 设置文本样式 - Font font = new Font("微软雅黑", 48, FontStyle.Bold); - Brush textBrush = new SolidBrush(Color.White); - StringFormat format = new StringFormat(); - format.Alignment = StringAlignment.Center; - format.LineAlignment = StringAlignment.Center; - - // 绘制"暂停"文字 - Console.WriteLine("Drawing '暂停' text"); - bufferGraphics.DrawString("暂停", font, textBrush, - new Rectangle(0, 0, bitmapWidth, bitmapHeight), format); - - // 将缓冲区内容绘制到目标位图 - bufferedGraphics.Render(g); + g.FillRectangle(brush, 0, 0, bitmapWidth, bitmapHeight); } + + // 设置文本样式 + Font font = new Font("微软雅黑", 48, FontStyle.Bold); + Brush textBrush = new SolidBrush(Color.White); + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + // 绘制"暂停"文字 + Console.WriteLine("Drawing '暂停' text"); + g.DrawString("暂停", font, textBrush, + new Rectangle(0, 0, bitmapWidth, bitmapHeight), format); } - // 在UI线程上更新maskImageBox - Console.WriteLine("Updating maskImageBox image"); - if (maskImageBox.InvokeRequired) + // 释放旧资源并设置新图像 + if (maskImageBox.Image != null) { - maskImageBox.Invoke(new Action(() => - { - // 先释放之前的图像资源 - if (maskImageBox.Image != null) - { - maskImageBox.Image.Dispose(); - } - maskImageBox.Image = bitmap; - maskImageBox.Visible = true; - Console.WriteLine("maskImageBox updated via Invoke"); - })); - } - else - { - // 先释放之前的图像资源 - if (maskImageBox.Image != null) - { - maskImageBox.Image.Dispose(); - } - maskImageBox.Image = bitmap; - maskImageBox.Visible = true; - Console.WriteLine("maskImageBox updated directly"); + maskImageBox.Image.Dispose(); } + maskImageBox.Image = bitmap; + maskImageBox.Visible = true; + Console.WriteLine("maskImageBox updated"); } else { // 清除遮罩 Console.WriteLine("Clearing maskImageBox image"); - if (maskImageBox.InvokeRequired) + if (maskImageBox.Image != null) { - maskImageBox.Invoke(new Action(() => - { - if (maskImageBox.Image != null) - { - maskImageBox.Image.Dispose(); - maskImageBox.Image = null; - } - Console.WriteLine("maskImageBox cleared via Invoke"); - })); - } - else - { - if (maskImageBox.Image != null) - { - maskImageBox.Image.Dispose(); - maskImageBox.Image = null; - } - Console.WriteLine("maskImageBox cleared directly"); + maskImageBox.Image.Dispose(); + maskImageBox.Image = null; } + maskImageBox.Visible = false; // 非暂停时隐藏遮罩 + Console.WriteLine("maskImageBox cleared"); } } catch (Exception ex) From 29c5757a1867d56f1c480185539770ae16e6d9dc Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 08:59:26 +0800 Subject: [PATCH 21/64] =?UTF-8?q?=E7=A1=AE=E4=BF=9DmaskImageBox=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E6=98=BE=E7=A4=BA=E5=9C=A8=E9=A1=B6=E5=B1=82=E4=BB=A5?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=9A=82=E5=81=9C=E5=AD=97=E6=A0=B7=E4=B8=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs index 69bd657..3a72337 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs @@ -192,6 +192,8 @@ namespace JoyD.Windows.CS.Toprie this.Controls.Add(this.imageBox); // 再添加maskImageBox遮罩层,确保它显示在上面 this.Controls.Add(this.maskImageBox); + // 确保maskImageBox显示在顶层 + this.maskImageBox.BringToFront(); this.Name = "Camera"; this.Size = new System.Drawing.Size(512, 384); this.Load += new System.EventHandler(this.Camera_Load); From 36d0ce4732475a25cef2be6f61a37c5eda2f5822 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 09:02:28 +0800 Subject: [PATCH 22/64] =?UTF-8?q?=E8=B0=83=E6=95=B4mask=E8=83=8C=E6=99=AF?= =?UTF-8?q?=E9=80=8F=E6=98=8E=E5=BA=A6=E4=BB=8E150=E9=99=8D=E4=BD=8E?= =?UTF-8?q?=E5=88=B080=EF=BC=8C=E8=AE=A9=E5=9B=BE=E5=83=8F=E5=9C=A8?= =?UTF-8?q?=E6=9A=82=E5=81=9C=E6=97=B6=E4=BB=8D=E5=8F=AF=E8=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index c7abc8f..c6afe43 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -135,8 +135,8 @@ namespace JoyD.Windows.CS.Toprie g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; - // 设置半透明背景 - using (Brush brush = new SolidBrush(Color.FromArgb(150, Color.Black))) + // 设置更透明的背景,50是透明度值,0完全透明,255不透明 + using (Brush brush = new SolidBrush(Color.FromArgb(80, Color.Black))) { g.FillRectangle(brush, 0, 0, bitmapWidth, bitmapHeight); } From fa98cbec65c5c2037947fb84feb45d5632ee0215 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 09:10:31 +0800 Subject: [PATCH 23/64] =?UTF-8?q?=E7=A7=BB=E9=99=A4mask=E5=B1=82=EF=BC=9A?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BA=86maskImageBox=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E7=9A=84=E6=89=80=E6=9C=89=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=8C=85?= =?UTF-8?q?=E6=8B=AC=E6=8E=A7=E4=BB=B6=E5=A3=B0=E6=98=8E=E3=80=81=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E5=92=8C=E7=9B=B8=E5=85=B3=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 110 ++---------------- 1 file changed, 8 insertions(+), 102 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index c6afe43..1307f32 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -19,8 +19,7 @@ namespace JoyD.Windows.CS.Toprie // 是否正在接收图像 private bool _isReceivingImage = false; - // 是否暂停图像更新 - private bool _isImageUpdatePaused = false; + // 项目路径,用于数据文件的存取 private string _projectPath = ""; @@ -70,22 +69,17 @@ namespace JoyD.Windows.CS.Toprie try { - // 切换暂停状态 - _isImageUpdatePaused = !_isImageUpdatePaused; + bool isPaused = pauseImageUpdateToolStripMenuItem.Text == "暂停图像更新"; - if (_isImageUpdatePaused) + if (isPaused) { pauseImageUpdateToolStripMenuItem.Text = "恢复图像更新"; Console.WriteLine("图像更新已暂停"); - // 显示暂停遮罩 - UpdateMaskDisplay(); } else { pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; Console.WriteLine("图像更新已恢复"); - // 清除暂停遮罩 - UpdateMaskDisplay(); // 恢复时,立即停止并重新开始图像接收,确保获取最新图像 if (_isReceivingImage && _deviceManager != null) @@ -100,87 +94,6 @@ namespace JoyD.Windows.CS.Toprie Console.WriteLine($"处理暂停/恢复图像更新时出错: {ex.Message}"); } } - - /// - /// 更新遮罩层的显示内容 - /// - private void UpdateMaskDisplay() - { - try - { - Console.WriteLine($"UpdateMaskDisplay called, _isImageUpdatePaused: {_isImageUpdatePaused}"); - - // 在UI线程上操作 - if (InvokeRequired) - { - Invoke(new Action(UpdateMaskDisplay)); - return; - } - - if (_isImageUpdatePaused) - { - // 使用固定大小512*384,与图像层的src图像大小一致 - const int bitmapWidth = 512; - const int bitmapHeight = 384; - - Console.WriteLine($"Creating bitmap with fixed size: {bitmapWidth}x{bitmapHeight}"); - - // 创建位图 - Bitmap bitmap = new Bitmap(bitmapWidth, bitmapHeight); - - // 直接在bitmap上绘制 - using (Graphics g = Graphics.FromImage(bitmap)) - { - // 设置高质量绘制 - g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; - g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; - - // 设置更透明的背景,50是透明度值,0完全透明,255不透明 - using (Brush brush = new SolidBrush(Color.FromArgb(80, Color.Black))) - { - g.FillRectangle(brush, 0, 0, bitmapWidth, bitmapHeight); - } - - // 设置文本样式 - Font font = new Font("微软雅黑", 48, FontStyle.Bold); - Brush textBrush = new SolidBrush(Color.White); - StringFormat format = new StringFormat(); - format.Alignment = StringAlignment.Center; - format.LineAlignment = StringAlignment.Center; - - // 绘制"暂停"文字 - Console.WriteLine("Drawing '暂停' text"); - g.DrawString("暂停", font, textBrush, - new Rectangle(0, 0, bitmapWidth, bitmapHeight), format); - } - - // 释放旧资源并设置新图像 - if (maskImageBox.Image != null) - { - maskImageBox.Image.Dispose(); - } - maskImageBox.Image = bitmap; - maskImageBox.Visible = true; - Console.WriteLine("maskImageBox updated"); - } - else - { - // 清除遮罩 - Console.WriteLine("Clearing maskImageBox image"); - if (maskImageBox.Image != null) - { - maskImageBox.Image.Dispose(); - maskImageBox.Image = null; - } - maskImageBox.Visible = false; // 非暂停时隐藏遮罩 - Console.WriteLine("maskImageBox cleared"); - } - } - catch (Exception ex) - { - Console.WriteLine($"更新遮罩显示时出错: {ex.Message}, StackTrace: {ex.StackTrace}"); - } - } public Camera() { @@ -410,9 +323,10 @@ namespace JoyD.Windows.CS.Toprie /// 设备管理器图像接收事件处理 /// private void DeviceManager_ImageReceived(object sender, ImageReceivedEventArgs e) - { + { // 如果图像更新已暂停,则不更新UI - if (_isImageUpdatePaused) + // 通过菜单项文本判断是否暂停 + if (pauseImageUpdateToolStripMenuItem.Text == "恢复图像更新") return; if (DesignMode) return; Image image = null; @@ -1145,15 +1059,7 @@ namespace JoyD.Windows.CS.Toprie /// private void ContextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e) { - // 更新暂停菜单项的文本和状态 - if (_isImageUpdatePaused) - { - pauseImageUpdateToolStripMenuItem.Text = "恢复图像更新"; - } - else - { - pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; - } + // 暂停菜单项的文本已经在点击事件中更新,这里无需再次更新 if (DesignMode) return; try { @@ -1183,7 +1089,7 @@ namespace JoyD.Windows.CS.Toprie rainbow2ToolStripMenuItem.Checked = false; // 尝试获取当前色彩模式并更新对应菜单项的选中状态 - if (!_isImageUpdatePaused && _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected) + if (pauseImageUpdateToolStripMenuItem.Text == "暂停图像更新" && _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected) { try { From 113fef2094a4f0942ddd9935266c4fed32cb7a2a Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 09:56:02 +0800 Subject: [PATCH 24/64] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E5=9B=BE=E5=83=8F=E6=9B=B4=E6=96=B0=E9=80=BB=E8=BE=91=EF=BC=9A?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0LastImage=E5=92=8CInfoImage=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 532 ++++++++++-------- 1 file changed, 288 insertions(+), 244 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 1307f32..08b3a55 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -19,7 +19,25 @@ namespace JoyD.Windows.CS.Toprie // 是否正在接收图像 private bool _isReceivingImage = false; - + // 全局图像缓冲区bitmap,用于在其上绘制图像和mask信息 + private Bitmap _imageBuffer = null; + private const int BUFFER_WIDTH = 512; + private const int BUFFER_HEIGHT = 384; + + // 最后接收的图像 + private Image _lastImage = null; + + // 信息图像,用于显示额外信息 + private Image _infoImage = null; + + // 用于保护_lastImage的线程锁 + private readonly object _lastImageLock = new object(); + + // 用于保护_infoImage的线程锁 + private readonly object _infoImageLock = new object(); + + // 是否显示信息图像 + private bool _isDisplayingInfo = false; // 项目路径,用于数据文件的存取 private string _projectPath = ""; @@ -43,10 +61,10 @@ namespace JoyD.Windows.CS.Toprie if (_deviceManager != null) { _deviceManager.ProjectPath = _projectPath; - } - } + } + } + } } - } // 显示错误的定时器 private System.Windows.Forms.Timer _errorDisplayTimer; @@ -93,8 +111,8 @@ namespace JoyD.Windows.CS.Toprie { Console.WriteLine($"处理暂停/恢复图像更新时出错: {ex.Message}"); } - } - + } + public Camera() { InitializeComponent(); @@ -105,6 +123,9 @@ namespace JoyD.Windows.CS.Toprie // 将设计模式状态传递给DeviceManager UpdateDesignModeStatus(); + // 初始化图像缓冲区 + InitializeImageBuffer(); + // 只有在非设计模式下才初始化设备管理器和错误定时器 if (!DesignMode) { @@ -180,7 +201,32 @@ namespace JoyD.Windows.CS.Toprie _deviceManager.ConnectionException += DeviceManager_ConnectionException; } } - + + /// + /// 初始化图像缓冲区 + /// + private void InitializeImageBuffer() + { + try + { + // 创建512*384大小的bitmap作为图像缓冲区 + _imageBuffer = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); + Console.WriteLine($"图像缓冲区已初始化: {BUFFER_WIDTH}x{BUFFER_HEIGHT}"); + + // 初始化缓冲区为黑色背景 + using (Graphics g = Graphics.FromImage(_imageBuffer)) + { + g.Clear(Color.Black); + } + } + catch (Exception ex) + { + Console.WriteLine($"初始化图像缓冲区失败: {ex.Message}"); + // 如果初始化失败,确保_imageBuffer为null + _imageBuffer = null; + } + } + /// /// 初始化错误显示定时器 /// @@ -329,7 +375,7 @@ namespace JoyD.Windows.CS.Toprie if (pauseImageUpdateToolStripMenuItem.Text == "恢复图像更新") return; if (DesignMode) return; - Image image = null; + try { if (e.ImageData != null && e.ImageData.Length > 0) @@ -344,306 +390,253 @@ namespace JoyD.Windows.CS.Toprie using (Image tempImage = System.Drawing.Image.FromStream(ms)) { // 创建一个全新的位图而不仅仅是克隆,确保数据完整性 - image = new Bitmap(tempImage); + Image newImage = new Bitmap(tempImage); // 立即验证新创建的图像是否有效 try { // 访问Width和Height属性来验证图像是否有效 - int width = image.Width; - int height = image.Height; + int width = newImage.Width; + int height = newImage.Height; if (width <= 0 || height <= 0) { Console.WriteLine("创建的图像尺寸无效"); - image.Dispose(); - image = null; + newImage.Dispose(); + return; } } catch (Exception) { Console.WriteLine("创建的图像无效"); - image.Dispose(); - image = null; + newImage.Dispose(); + return; } - } - } - } - } - } - catch (Exception ex) - { - Console.WriteLine($"创建图像失败: {ex.Message}"); - // 确保在异常情况下释放资源 - if (image != null) - { - image.Dispose(); - image = null; - } - } - - if (image == null) - { - Console.WriteLine("接收到空或无效的图像数据"); - return; - } - - try - { - // 尝试创建图像的克隆以传递给UI线程 - Image clonedImage = null; - try - { - clonedImage = (Image)image.Clone(); - - // 验证克隆的图像是否有效 - if (clonedImage.Width <= 0 || clonedImage.Height <= 0) - { - Console.WriteLine("克隆的图像尺寸无效"); - clonedImage.Dispose(); - image.Dispose(); // 确保原始图像也被释放 - return; - } - } - catch (Exception ex) - { - Console.WriteLine($"克隆图像失败: {ex.Message}"); - image.Dispose(); // 确保原始图像被释放 - return; - } - - // 确保在UI线程上更新,并且检查控件是否已被释放 - if (!this.IsDisposed && !this.Disposing) - { - if (this.InvokeRequired) - { - try - { - // 创建本地副本以避免闭包问题 - Image imageForUI = clonedImage; - clonedImage = null; // 防止在异步操作期间被修改 - - // 使用BeginInvoke在UI线程上更新图像,避免可能的死锁问题 - this.BeginInvoke(new Action(() => - { - try + + // 按照用户要求:收到图像数据后,将图像保存到LastImage中,调用更新 + lock (_lastImageLock) { - UpdateImageOnUI(imageForUI); - } - catch (Exception ex) - { - Console.WriteLine($"更新UI图像失败: {ex.Message}"); - // 如果UI更新失败,确保克隆的图像被释放 - if (imageForUI != null) + // 释放旧的LastImage资源 + if (_lastImage != null) { - try - { - imageForUI.Dispose(); - } - catch {} + try { _lastImage.Dispose(); } catch {} } + // 设置新的LastImage + _lastImage = newImage; } - })); - } - catch (Exception) - { - // 异常情况下确保释放图像资源 - if (clonedImage != null) - { - try + + // 调用更新UI + this.BeginInvoke(new Action(() => { - clonedImage.Dispose(); - } - catch {} - clonedImage = null; + try + { + UpdateImageOnUI(); + } + catch (Exception ex) + { + Console.WriteLine($"更新UI图像失败: {ex.Message}"); + } + })); } - throw; } } - else - { - // 在UI线程上直接更新图像 - UpdateImageOnUI(clonedImage); - } } - else - { - // 如果控件已释放,确保释放图像资源 - clonedImage.Dispose(); - } - - // 释放原始图像资源 - image.Dispose(); } catch (Exception ex) { - Console.WriteLine($"处理图像接收事件失败: {ex.Message}"); - // 确保在任何异常情况下都释放原始图像 - if (image != null) - { - try - { - image.Dispose(); - } - catch {} - } + Console.WriteLine($"处理接收到的图像时出错: {ex.Message}"); } } /// /// 在UI线程上更新图像 /// - private void UpdateImageOnUI(Image image) - { + private void UpdateImageOnUI(Image image) // 保留原有方法签名,处理旧调用 + { + UpdateImageOnUI(); + } + + /// + /// 在UI线程上更新图像 - 新实现,按照用户要求: + /// 1. 先将LastImage绘制到全局缓冲 + /// 2. 再将InfoImage绘制到缓冲 + /// 3. 最后一次性绘制到图像框的bitmap + /// + private void UpdateImageOnUI() + { if (DesignMode) return; + // 线程安全检查 - 确保在UI线程上执行 if (this.InvokeRequired) - { + { try - { - this.BeginInvoke(new Action(UpdateImageOnUI), image); + { + this.BeginInvoke(new Action(UpdateImageOnUI)); } catch (ObjectDisposedException) - { - // 如果控件已被释放,确保释放图像资源 - if (image != null) - { - try { image.Dispose(); } catch {} - } + { Console.WriteLine("控件已释放,跳过UI更新"); } return; } - // 空值检查 - if (image == null) - { - Console.WriteLine("传入UpdateImageOnUI的图像为空"); - return; - } - // 连接状态检查 - 只在设备实际连接时处理图像 - if (_deviceManager.ConnectionStatus != ConnectionStatus.Connected) - { - Console.WriteLine("设备未连接,跳过图像更新"); - try { image.Dispose(); } catch {} - return; - } - // 增强图像有效性检查 - bool isImageValid = false; - Image safeImage = null; + Image lastImage = null; + Image infoImage = null; + Image oldImage = null; try - { - // 创建一个安全的图像副本,确保原图像不被破坏 - safeImage = new Bitmap(image); + { + // 连接状态检查 - 只在设备实际连接时处理图像 + if (_deviceManager.ConnectionStatus != ConnectionStatus.Connected) + { + Console.WriteLine("设备未连接,跳过图像更新"); + return; + } - // 预先验证图像是否有效 - if (safeImage.Width > 0 && safeImage.Height > 0) - { - // 尝试访问图像的像素数据,这是更严格的验证方式 - using (Graphics g = Graphics.FromImage(new Bitmap(1, 1))) - { - // 简单绘制操作验证图像是否可绘制 - g.DrawImage(safeImage, 0, 0, 1, 1); + // 检查图像缓冲区是否有效 + if (_imageBuffer == null) + { + Console.WriteLine("图像缓冲区未初始化,尝试重新初始化"); + InitializeImageBuffer(); + if (_imageBuffer == null) + { + Console.WriteLine("重新初始化图像缓冲区失败"); + return; } - isImageValid = true; - Console.WriteLine($"图像验证成功: {safeImage.Width}x{safeImage.Height}"); } - else - { - Console.WriteLine($"图像尺寸无效: {safeImage.Width}x{safeImage.Height}"); - } - } - catch (Exception ex) - { - Console.WriteLine($"图像验证失败: {ex.Message}"); - // 释放临时创建的安全图像 - if (safeImage != null) - { - try { safeImage.Dispose(); } catch {} - } - // 释放原始图像 - try { image.Dispose(); } catch {} - return; - } - - try - { + // 更新图像前先检查控件是否存在/已释放 if (this.IsDisposed || imageBox == null || imageBox.IsDisposed) - { - // 如果控件已释放,确保图像也被释放 - try { safeImage.Dispose(); } catch {} - try { image.Dispose(); } catch {} + { Console.WriteLine("控件已释放,无法更新图像"); return; } // 保存旧图像引用,以便在设置新图像后释放 - Image oldImage = imageBox.Image; + oldImage = imageBox.Image; - try - { - // 确保控件仍处于有效状态 - if (imageBox.IsDisposed || !isImageValid || safeImage == null) - { - try { safeImage.Dispose(); } catch {} - try { image.Dispose(); } catch {} - return; - } - - // 尝试设置新图像(使用验证过的安全副本) - imageBox.Image = safeImage; - - // 验证图像是否成功设置 - if (imageBox.Image != safeImage) - { - Console.WriteLine("图像设置失败,可能参数无效"); - try { safeImage.Dispose(); } catch {} - try { image.Dispose(); } catch {} - return; - } - - // 释放原始图像,因为我们现在使用的是安全副本 - try { image.Dispose(); } catch {} - - // 仅在新图像成功设置后释放旧图像 - if (oldImage != null && oldImage != safeImage) // 防止自引用释放 - { - try - { - oldImage.Dispose(); - } - catch {} + // 获取当前的LastImage引用 + lock (_lastImageLock) + { + if (_lastImage != null) + { + lastImage = (Image)_lastImage.Clone(); } } - catch (ArgumentException ex) when (ex.Message.Contains("参数无效")) - { - // 特别处理"参数无效"异常 - Console.WriteLine($"图像参数无效异常: {ex.Message}"); - try { safeImage.Dispose(); } catch {} - try { image.Dispose(); } catch {} - - // 尝试设置旧图像回来,如果可能的话 - if (oldImage != null) - { - try - { - imageBox.Image = oldImage; + + // 获取当前的InfoImage引用 + lock (_infoImageLock) + { + if (_infoImage != null) + { + infoImage = (Image)_infoImage.Clone(); + } + } + + // 在缓冲区上绘制图像 - 按照用户要求的步骤执行 + lock (_imageBuffer) + { + using (Graphics g = Graphics.FromImage(_imageBuffer)) + { + // 清除缓冲区背景为黑色 + g.Clear(Color.Black); + + // 步骤1:先将LastImage绘制到全局缓冲 + if (lastImage != null) + { + // 保持原始图像比例,居中显示 + float scale = Math.Min((float)BUFFER_WIDTH / lastImage.Width, (float)BUFFER_HEIGHT / lastImage.Height); + int scaledWidth = (int)(lastImage.Width * scale); + int scaledHeight = (int)(lastImage.Height * scale); + int x = (BUFFER_WIDTH - scaledWidth) / 2; + int y = (BUFFER_HEIGHT - scaledHeight) / 2; + + g.DrawImage(lastImage, x, y, scaledWidth, scaledHeight); } - catch - { - // 如果设置旧图像也失败,释放它 - try { oldImage.Dispose(); } catch {} + + // 步骤2:再将InfoImage绘制到缓冲 + if (infoImage != null) + { + g.DrawImage(infoImage, 0, 0); } + else if (_isDisplayingInfo) + { + // 如果没有InfoImage但需要显示信息,则绘制默认信息 + using (Font font = new Font("微软雅黑", 12, FontStyle.Bold)) + using (Brush textBrush = new SolidBrush(Color.Red)) + { + g.DrawString("测试信息", font, textBrush, 10, 10); + } + } + + // 检查是否需要绘制暂停状态的mask信息 + bool isPaused = pauseImageUpdateToolStripMenuItem.Text == "恢复图像更新"; + if (isPaused) + { + // 绘制半透明黑色背景 + using (Brush brush = new SolidBrush(Color.FromArgb(100, Color.Black))) + { + g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); + } + + // 绘制"暂停"文字 + using (Font font = new Font("微软雅黑", 48, FontStyle.Bold)) + using (Brush textBrush = new SolidBrush(Color.White)) + { + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + + g.DrawString("暂停", font, textBrush, + new Rectangle(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format); + } + } + } + } + + // 步骤3:创建缓冲区的副本用于显示,避免在显示时锁定缓冲区 + Bitmap displayImage = null; + lock (_imageBuffer) + { + displayImage = (Bitmap)_imageBuffer.Clone(); + } + + // 将全局缓冲一次性绘制到图像框的bitmap + imageBox.Image = displayImage; + + if (lastImage != null) + { + Console.WriteLine($"图像更新成功: {lastImage.Width}x{lastImage.Height}"); + } + } + catch (ArgumentException ex) when (ex.Message.Contains("参数无效")) + { + // 特别处理"参数无效"异常 + Console.WriteLine($"图像参数无效异常: {ex.Message}"); + + // 尝试设置旧图像回来,如果可能的话 + if (oldImage != null && !this.IsDisposed && imageBox != null && !imageBox.IsDisposed) + { + try + { + imageBox.Image = oldImage; + } + catch + { + // 如果设置旧图像也失败,释放它 + try { oldImage.Dispose(); } catch {} } } } catch (Exception ex) - { + { Console.WriteLine($"更新图像UI异常: {ex.Message}"); - // 确保在任何异常情况下都释放所有图像资源 - try { safeImage.Dispose(); } catch {} - try { image.Dispose(); } catch {} + } + finally + { + // 确保在任何情况下都释放资源 + if (lastImage != null) { try { lastImage.Dispose(); } catch { } } + if (infoImage != null) { try { infoImage.Dispose(); } catch { } } + if (oldImage != null && oldImage != imageBox.Image) { try { oldImage.Dispose(); } catch { } } } } @@ -1383,11 +1376,62 @@ namespace JoyD.Windows.CS.Toprie // 无论是否在设计模式下,都需要释放图像资源 if (imageBox != null && !imageBox.IsDisposed && imageBox.Image != null) - { + { imageBox.Image.Dispose(); imageBox.Image = null; } + // 释放图像缓冲区资源 + if (_imageBuffer != null) + { + try + { + _imageBuffer.Dispose(); + _imageBuffer = null; + Console.WriteLine("图像缓冲区资源已释放"); + } + catch (Exception ex) + { + Console.WriteLine($"清理ImageBuffer资源异常: {ex.Message}"); + } + } + + // 释放LastImage资源 + lock (_lastImageLock) + { + if (_lastImage != null) + { + try + { + _lastImage.Dispose(); + _lastImage = null; + Console.WriteLine("LastImage资源已释放"); + } + catch (Exception ex) + { + Console.WriteLine($"清理LastImage资源异常: {ex.Message}"); + } + } + } + + // 释放InfoImage资源 + lock (_infoImageLock) + { + if (_infoImage != null) + { + try + { + _infoImage.Dispose(); + _infoImage = null; + Console.WriteLine("InfoImage资源已释放"); + } + catch (Exception ex) + { + Console.WriteLine($"清理InfoImage资源异常: {ex.Message}"); + } + } + } + // 释放组件资源 if (components != null) { From 0f8382576d827d2c803f41dab40de658ff4d0b33 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 09:58:59 +0800 Subject: [PATCH 25/64] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=9A=82=E5=81=9C?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=97=B6=E5=9C=A8InfoImage=E4=B8=AD=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E6=9A=82=E5=81=9C=E5=AD=97=E6=A0=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 08b3a55..67c7a7d 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -93,12 +93,75 @@ namespace JoyD.Windows.CS.Toprie { pauseImageUpdateToolStripMenuItem.Text = "恢复图像更新"; Console.WriteLine("图像更新已暂停"); + + // 在InfoImage中绘制暂停字样 + lock (_infoImageLock) + { + // 释放之前的InfoImage资源 + if (_infoImage != null) + { + try + { + _infoImage.Dispose(); + } + catch (Exception ex) + { + Console.WriteLine($"释放InfoImage资源异常: {ex.Message}"); + } + } + + // 创建新的InfoImage并绘制暂停字样 + _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); + using (Graphics g = Graphics.FromImage(_infoImage)) + { + // 设置半透明背景 + using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black))) + { + g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); + } + + // 绘制暂停字样 + using (Font font = new Font("Arial", 48, FontStyle.Bold)) + using (SolidBrush textBrush = new SolidBrush(Color.Red)) + { + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + g.DrawString("暂停", font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format); + } + } + } + + // 设置显示信息标志并更新UI + _isDisplayingInfo = true; + UpdateImageOnUI(); } else { pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; Console.WriteLine("图像更新已恢复"); + // 清除InfoImage和显示标志 + lock (_infoImageLock) + { + if (_infoImage != null) + { + try + { + _infoImage.Dispose(); + _infoImage = null; + } + catch (Exception ex) + { + Console.WriteLine($"释放InfoImage资源异常: {ex.Message}"); + } + } + } + _isDisplayingInfo = false; + + // 立即更新UI + UpdateImageOnUI(); + // 恢复时,立即停止并重新开始图像接收,确保获取最新图像 if (_isReceivingImage && _deviceManager != null) { From 4bdd1b2790ac8a6fee3ea1ab045d47388391ae70 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 10:05:29 +0800 Subject: [PATCH 26/64] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=9A=82=E5=81=9C?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E4=B8=8B=E9=9A=90=E8=97=8F=E5=9B=BE=E5=83=8F?= =?UTF-8?q?=E5=92=8C=E8=89=B2=E5=BD=A9=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 174 ++++++++++-------- 1 file changed, 102 insertions(+), 72 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 67c7a7d..77ed943 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -1113,96 +1113,126 @@ namespace JoyD.Windows.CS.Toprie /// 右键菜单显示前的事件处理方法 /// 用于更新色彩模式菜单项的选中状态 /// + /// + /// 右键菜单打开事件处理 + /// private void ContextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e) { // 暂停菜单项的文本已经在点击事件中更新,这里无需再次更新 if (DesignMode) return; try { - // 根据当前图像模式控制色彩模式菜单的可见性 - if (_deviceManager != null) + // 检查是否处于暂停状态 + bool isPaused = pauseImageUpdateToolStripMenuItem.Text == "恢复图像更新"; + + // 在暂停状态下,隐藏图像和色彩相关菜单 + if (isPaused) { - colorModeToolStripMenuItem.Visible = _deviceManager.CurrentImageMode == ImageMode.Infrared; + thermalModeToolStripMenuItem.Visible = false; + visibleModeToolStripMenuItem.Visible = false; + fusionMode1ToolStripMenuItem.Visible = false; + fusionMode2ToolStripMenuItem.Visible = false; + fusionMode3ToolStripMenuItem.Visible = false; + fusionMode4ToolStripMenuItem.Visible = false; + fusionMode5ToolStripMenuItem.Visible = false; + colorModeToolStripMenuItem.Visible = false; } - - // 清除视频模式菜单项的选中状态 - thermalModeToolStripMenuItem.Checked = false; - visibleModeToolStripMenuItem.Checked = false; - fusionMode1ToolStripMenuItem.Checked = false; - fusionMode2ToolStripMenuItem.Checked = false; - fusionMode3ToolStripMenuItem.Checked = false; - fusionMode4ToolStripMenuItem.Checked = false; - fusionMode5ToolStripMenuItem.Checked = false; - - // 清除色彩模式菜单项的选中状态 - whiteHotToolStripMenuItem.Checked = false; - blackHotToolStripMenuItem.Checked = false; - ironRedToolStripMenuItem.Checked = false; - lavaToolStripMenuItem.Checked = false; - rainbowToolStripMenuItem.Checked = false; - ironGrayToolStripMenuItem.Checked = false; - redHotToolStripMenuItem.Checked = false; - rainbow2ToolStripMenuItem.Checked = false; - - // 尝试获取当前色彩模式并更新对应菜单项的选中状态 - if (pauseImageUpdateToolStripMenuItem.Text == "暂停图像更新" && _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected) + else { - try + // 在非暂停状态下,显示图像模式相关菜单 + thermalModeToolStripMenuItem.Visible = true; + visibleModeToolStripMenuItem.Visible = true; + fusionMode1ToolStripMenuItem.Visible = true; + fusionMode2ToolStripMenuItem.Visible = true; + fusionMode3ToolStripMenuItem.Visible = true; + fusionMode4ToolStripMenuItem.Visible = true; + fusionMode5ToolStripMenuItem.Visible = true; + + // 根据当前图像模式控制色彩模式菜单的可见性 + if (_deviceManager != null) { - // 获取当前色彩模式 - PaletteType currentPalette = _deviceManager.CurrentPaletteType; - - // 根据当前色彩模式设置对应菜单项的选中状态 - switch (currentPalette) - { - case PaletteType.WhiteHot: - whiteHotToolStripMenuItem.Checked = true; - break; - case PaletteType.BlackHot: - blackHotToolStripMenuItem.Checked = true; - break; - case PaletteType.IronRed: - ironRedToolStripMenuItem.Checked = true; - break; - case PaletteType.Lava: - lavaToolStripMenuItem.Checked = true; - break; - case PaletteType.Rainbow: - rainbowToolStripMenuItem.Checked = true; - break; - case PaletteType.IronGray: - ironGrayToolStripMenuItem.Checked = true; - break; - case PaletteType.RedHot: - redHotToolStripMenuItem.Checked = true; - break; - case PaletteType.Rainbow2: - rainbow2ToolStripMenuItem.Checked = true; - break; - } - } - catch (Exception ex) - { - Console.WriteLine("获取当前色彩模式失败: " + ex.Message); + colorModeToolStripMenuItem.Visible = _deviceManager.CurrentImageMode == ImageMode.Infrared; } - // 更新视频模式菜单项的选中状态 - try + // 清除视频模式菜单项的选中状态 + thermalModeToolStripMenuItem.Checked = false; + visibleModeToolStripMenuItem.Checked = false; + fusionMode1ToolStripMenuItem.Checked = false; + fusionMode2ToolStripMenuItem.Checked = false; + fusionMode3ToolStripMenuItem.Checked = false; + fusionMode4ToolStripMenuItem.Checked = false; + fusionMode5ToolStripMenuItem.Checked = false; + + // 清除色彩模式菜单项的选中状态 + whiteHotToolStripMenuItem.Checked = false; + blackHotToolStripMenuItem.Checked = false; + ironRedToolStripMenuItem.Checked = false; + lavaToolStripMenuItem.Checked = false; + rainbowToolStripMenuItem.Checked = false; + ironGrayToolStripMenuItem.Checked = false; + redHotToolStripMenuItem.Checked = false; + rainbow2ToolStripMenuItem.Checked = false; + + // 尝试获取当前色彩模式并更新对应菜单项的选中状态 + if (_deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected) { - // 更改为使用ImageMode枚举 - var currentImageMode = _deviceManager.CurrentImageMode; - thermalModeToolStripMenuItem.Checked = currentImageMode == ImageMode.Infrared; - visibleModeToolStripMenuItem.Checked = currentImageMode == ImageMode.Natural; - } - catch (Exception ex) - { - Console.WriteLine("获取当前图像模式失败: " + ex.Message); + try + { + // 获取当前色彩模式 + PaletteType currentPalette = _deviceManager.CurrentPaletteType; + + // 根据当前色彩模式设置对应菜单项的选中状态 + switch (currentPalette) + { + case PaletteType.WhiteHot: + whiteHotToolStripMenuItem.Checked = true; + break; + case PaletteType.BlackHot: + blackHotToolStripMenuItem.Checked = true; + break; + case PaletteType.IronRed: + ironRedToolStripMenuItem.Checked = true; + break; + case PaletteType.Lava: + lavaToolStripMenuItem.Checked = true; + break; + case PaletteType.Rainbow: + rainbowToolStripMenuItem.Checked = true; + break; + case PaletteType.IronGray: + ironGrayToolStripMenuItem.Checked = true; + break; + case PaletteType.RedHot: + redHotToolStripMenuItem.Checked = true; + break; + case PaletteType.Rainbow2: + rainbow2ToolStripMenuItem.Checked = true; + break; + } + } + catch (Exception ex) + { + Console.WriteLine($"获取当前色彩模式失败: {ex.Message}"); + } + + // 更新视频模式菜单项的选中状态 + try + { + // 更改为使用ImageMode枚举 + var currentImageMode = _deviceManager.CurrentImageMode; + thermalModeToolStripMenuItem.Checked = currentImageMode == ImageMode.Infrared; + visibleModeToolStripMenuItem.Checked = currentImageMode == ImageMode.Natural; + } + catch (Exception ex) + { + Console.WriteLine($"获取当前图像模式失败: {ex.Message}"); + } } } } catch (Exception ex) { - Console.WriteLine("更新右键菜单选中状态失败: " + ex.Message); + Console.WriteLine($"更新右键菜单选中状态失败: {ex.Message}"); } } From 02468e6fbcca181600281d754c69642b4473600b Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 10:17:09 +0800 Subject: [PATCH 27/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9B=BE=E5=83=8F?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E6=A0=B9=E8=8F=9C=E5=8D=95=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E6=9A=82=E5=81=9C=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E4=B8=8B=E9=9A=90=E8=97=8F=E5=9B=BE=E5=83=8F=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E6=A0=B9=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 77ed943..4c03602 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -452,7 +452,7 @@ namespace JoyD.Windows.CS.Toprie // 从流中创建图像 using (Image tempImage = System.Drawing.Image.FromStream(ms)) { - // 创建一个全新的位图而不仅仅是克隆,确保数据完整性 + // 创建一个全新的位图而仅仅是克隆,确保数据完整性 Image newImage = new Bitmap(tempImage); // 立即验证新创建的图像是否有效 @@ -1128,6 +1128,10 @@ namespace JoyD.Windows.CS.Toprie // 在暂停状态下,隐藏图像和色彩相关菜单 if (isPaused) { + // 隐藏图像模式根菜单和所有子菜单 + if (imageModeToolStripMenuItem != null) + imageModeToolStripMenuItem.Visible = false; + thermalModeToolStripMenuItem.Visible = false; visibleModeToolStripMenuItem.Visible = false; fusionMode1ToolStripMenuItem.Visible = false; @@ -1139,7 +1143,10 @@ namespace JoyD.Windows.CS.Toprie } else { - // 在非暂停状态下,显示图像模式相关菜单 + // 在非暂停状态下,显示图像模式根菜单和相关子菜单 + if (imageModeToolStripMenuItem != null) + imageModeToolStripMenuItem.Visible = true; + thermalModeToolStripMenuItem.Visible = true; visibleModeToolStripMenuItem.Visible = true; fusionMode1ToolStripMenuItem.Visible = true; From 7037d28f0a4927f7ce3bc0a275f4d9f721e9487c Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 10:19:13 +0800 Subject: [PATCH 28/64] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BB=85=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E6=A0=B9=E8=8F=9C=E5=8D=95=E5=8F=AF=E8=A7=81=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 4c03602..788bd0b 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -1125,36 +1125,24 @@ namespace JoyD.Windows.CS.Toprie // 检查是否处于暂停状态 bool isPaused = pauseImageUpdateToolStripMenuItem.Text == "恢复图像更新"; - // 在暂停状态下,隐藏图像和色彩相关菜单 + // 在暂停状态下,隐藏图像模式根菜单和色彩模式菜单 + // 注意:根菜单隐藏后,其所有子菜单会自动隐藏,不需要单独设置 if (isPaused) { - // 隐藏图像模式根菜单和所有子菜单 + // 隐藏图像模式根菜单 if (imageModeToolStripMenuItem != null) imageModeToolStripMenuItem.Visible = false; - thermalModeToolStripMenuItem.Visible = false; - visibleModeToolStripMenuItem.Visible = false; - fusionMode1ToolStripMenuItem.Visible = false; - fusionMode2ToolStripMenuItem.Visible = false; - fusionMode3ToolStripMenuItem.Visible = false; - fusionMode4ToolStripMenuItem.Visible = false; - fusionMode5ToolStripMenuItem.Visible = false; + // 隐藏色彩模式菜单 colorModeToolStripMenuItem.Visible = false; } else { - // 在非暂停状态下,显示图像模式根菜单和相关子菜单 + // 在非暂停状态下,显示图像模式根菜单 + // 注意:根菜单显示后,其所有子菜单会自动显示,不需要单独设置 if (imageModeToolStripMenuItem != null) imageModeToolStripMenuItem.Visible = true; - thermalModeToolStripMenuItem.Visible = true; - visibleModeToolStripMenuItem.Visible = true; - fusionMode1ToolStripMenuItem.Visible = true; - fusionMode2ToolStripMenuItem.Visible = true; - fusionMode3ToolStripMenuItem.Visible = true; - fusionMode4ToolStripMenuItem.Visible = true; - fusionMode5ToolStripMenuItem.Visible = true; - // 根据当前图像模式控制色彩模式菜单的可见性 if (_deviceManager != null) { From ccc100f04960b983e1f10cd0c29787d13694b8d1 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 10:21:05 +0800 Subject: [PATCH 29/64] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=88=86=E9=9A=94?= =?UTF-8?q?=E7=AC=A6=E6=98=BE=E7=A4=BA=E6=8E=A7=E5=88=B6=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E8=8F=9C=E5=8D=95=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 788bd0b..c327d0a 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -1135,6 +1135,9 @@ namespace JoyD.Windows.CS.Toprie // 隐藏色彩模式菜单 colorModeToolStripMenuItem.Visible = false; + + // 当只有一个菜单项可见时,隐藏分隔符 + toolStripSeparator1.Visible = false; } else { @@ -1143,6 +1146,9 @@ namespace JoyD.Windows.CS.Toprie if (imageModeToolStripMenuItem != null) imageModeToolStripMenuItem.Visible = true; + // 在非暂停状态下,显示分隔符 + toolStripSeparator1.Visible = true; + // 根据当前图像模式控制色彩模式菜单的可见性 if (_deviceManager != null) { From 8820857d8aa972dd72f6db5af89fc6ffb344b845 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 10:30:55 +0800 Subject: [PATCH 30/64] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=AD=E5=BC=80?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E5=92=8C=E9=87=8D=E8=BF=9E=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E7=9A=84InfoImage=E6=98=BE=E7=A4=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 107 +++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index c327d0a..6cf64a9 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -808,6 +808,24 @@ namespace JoyD.Windows.CS.Toprie case ConnectionStatus.Connected: Console.WriteLine("设备已连接"); + // 清除InfoImage和显示标志 + lock (_infoImageLock) + { + if (_infoImage != null) + { + try + { + _infoImage.Dispose(); + _infoImage = null; + } + catch (Exception ex) + { + Console.WriteLine($"释放InfoImage资源异常: {ex.Message}"); + } + } + } + _isDisplayingInfo = false; + // 清除错误信息 ShowError(string.Empty); @@ -856,6 +874,48 @@ namespace JoyD.Windows.CS.Toprie } } + // 在InfoImage中显示连接断开信息 + lock (_infoImageLock) + { + // 释放之前的InfoImage资源 + if (_infoImage != null) + { + try + { + _infoImage.Dispose(); + } + catch (Exception ex) + { + Console.WriteLine($"释放InfoImage资源异常: {ex.Message}"); + } + } + + // 创建新的InfoImage并绘制断开连接字样 + _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); + using (Graphics g = Graphics.FromImage(_infoImage)) + { + // 设置半透明背景 + using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black))) + { + g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); + } + + // 绘制断开连接字样 + using (Font font = new Font("Arial", 36, FontStyle.Bold)) + using (SolidBrush textBrush = new SolidBrush(Color.Red)) + { + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + g.DrawString("连接断开", font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format); + } + } + } + + // 设置显示信息标志并更新UI + _isDisplayingInfo = true; + UpdateImageOnUI(); + if (!string.IsNullOrEmpty(e.DeviceInfo)) { ShowError(e.DeviceInfo); @@ -866,10 +926,55 @@ namespace JoyD.Windows.CS.Toprie } break; case ConnectionStatus.Connecting: - case ConnectionStatus.Reconnecting: Console.WriteLine($"正在连接设备...{(!string.IsNullOrEmpty(e.DeviceInfo) ? " " + e.DeviceInfo : "")}"); ShowError(string.Empty); // 清除之前的错误信息 break; + case ConnectionStatus.Reconnecting: + Console.WriteLine($"正在重新连接设备...{(!string.IsNullOrEmpty(e.DeviceInfo) ? " " + e.DeviceInfo : "")}"); + ShowError(string.Empty); // 清除之前的错误信息 + + // 在InfoImage中显示正在重连信息 + lock (_infoImageLock) + { + // 释放之前的InfoImage资源 + if (_infoImage != null) + { + try + { + _infoImage.Dispose(); + } + catch (Exception ex) + { + Console.WriteLine($"释放InfoImage资源异常: {ex.Message}"); + } + } + + // 创建新的InfoImage并绘制正在重连字样 + _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); + using (Graphics g = Graphics.FromImage(_infoImage)) + { + // 设置半透明背景 + using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black))) + { + g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); + } + + // 绘制正在重连字样 + using (Font font = new Font("Arial", 36, FontStyle.Bold)) + using (SolidBrush textBrush = new SolidBrush(Color.Yellow)) + { + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + g.DrawString("正在重连...", font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format); + } + } + } + + // 设置显示信息标志并更新UI + _isDisplayingInfo = true; + UpdateImageOnUI(); + break; } } catch (Exception ex) From 1261e861cc04e12b5df8bee8fd90db7315e0d6a5 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 10:34:03 +0800 Subject: [PATCH 31/64] =?UTF-8?q?=E4=BC=98=E5=8C=96InfoImage=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=96=B9=E5=BC=8F=EF=BC=8C=E9=81=BF=E5=85=8D=E9=A2=91?= =?UTF-8?q?=E7=B9=81Dispose=EF=BC=8C=E6=94=B9=E4=B8=BA=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E6=B8=85=E9=99=A4=E5=B9=B6=E9=87=8D=E7=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 45 ++++--------------- 1 file changed, 9 insertions(+), 36 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 6cf64a9..4d52668 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -811,18 +811,7 @@ namespace JoyD.Windows.CS.Toprie // 清除InfoImage和显示标志 lock (_infoImageLock) { - if (_infoImage != null) - { - try - { - _infoImage.Dispose(); - _infoImage = null; - } - catch (Exception ex) - { - Console.WriteLine($"释放InfoImage资源异常: {ex.Message}"); - } - } + _infoImage = null; // 直接设为null,不需要Dispose } _isDisplayingInfo = false; @@ -877,21 +866,13 @@ namespace JoyD.Windows.CS.Toprie // 在InfoImage中显示连接断开信息 lock (_infoImageLock) { - // 释放之前的InfoImage资源 - if (_infoImage != null) + // 如果_infoImage为null,则创建新对象 + if (_infoImage == null) { - try - { - _infoImage.Dispose(); - } - catch (Exception ex) - { - Console.WriteLine($"释放InfoImage资源异常: {ex.Message}"); - } + _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); } - // 创建新的InfoImage并绘制断开连接字样 - _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); + // 直接在现有InfoImage上重绘,不需要Dispose using (Graphics g = Graphics.FromImage(_infoImage)) { // 设置半透明背景 @@ -936,21 +917,13 @@ namespace JoyD.Windows.CS.Toprie // 在InfoImage中显示正在重连信息 lock (_infoImageLock) { - // 释放之前的InfoImage资源 - if (_infoImage != null) + // 如果_infoImage为null,则创建新对象 + if (_infoImage == null) { - try - { - _infoImage.Dispose(); - } - catch (Exception ex) - { - Console.WriteLine($"释放InfoImage资源异常: {ex.Message}"); - } + _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); } - // 创建新的InfoImage并绘制正在重连字样 - _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); + // 直接在现有InfoImage上重绘,不需要Dispose using (Graphics g = Graphics.FromImage(_infoImage)) { // 设置半透明背景 From 4412fda9540b02fd2d514b0a205cdedaf4730b38 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 10:35:48 +0800 Subject: [PATCH 32/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8DConnected=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E4=B8=8B=5FinfoImage=E6=9C=AADispose=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E7=9A=84=E5=86=85=E5=AD=98=E6=B3=84=E6=BC=8F=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 4d52668..6b75f86 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -811,7 +811,11 @@ namespace JoyD.Windows.CS.Toprie // 清除InfoImage和显示标志 lock (_infoImageLock) { - _infoImage = null; // 直接设为null,不需要Dispose + if (_infoImage != null) + { + _infoImage.Dispose(); + _infoImage = null; + } } _isDisplayingInfo = false; From 1a9dffafd19d0bf1408f35d89e1f7945cce4231a Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 10:36:45 +0800 Subject: [PATCH 33/64] =?UTF-8?q?=E4=BF=AE=E6=94=B9=5FinfoImage=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=96=B9=E5=BC=8F=EF=BC=8CDispose=E5=90=8E=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E8=AE=BE=E4=B8=BAnull?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 6b75f86..3046a95 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -814,7 +814,6 @@ namespace JoyD.Windows.CS.Toprie if (_infoImage != null) { _infoImage.Dispose(); - _infoImage = null; } } _isDisplayingInfo = false; From ff1de1a77091bcb5e042f04fd8c63346b0462d96 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 10:37:54 +0800 Subject: [PATCH 34/64] =?UTF-8?q?=E7=A7=BB=E9=99=A4Connected=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E4=B8=8B=E4=B8=8D=E5=BF=85=E8=A6=81=E7=9A=84InfoImage?= =?UTF-8?q?=E5=A4=84=E7=90=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 3046a95..ad9695a 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -808,14 +808,7 @@ namespace JoyD.Windows.CS.Toprie case ConnectionStatus.Connected: Console.WriteLine("设备已连接"); - // 清除InfoImage和显示标志 - lock (_infoImageLock) - { - if (_infoImage != null) - { - _infoImage.Dispose(); - } - } + // 清除显示标志 _isDisplayingInfo = false; // 清除错误信息 From a6e16ef46bce734ccd8a2a0912ccb58a5db8c9cd Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 10:41:05 +0800 Subject: [PATCH 35/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E5=90=8EInfoImage=E4=BB=8D=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E6=AD=A3=E5=9C=A8=E9=87=8D=E8=BF=9E=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index ad9695a..135110a 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -808,8 +808,9 @@ namespace JoyD.Windows.CS.Toprie case ConnectionStatus.Connected: Console.WriteLine("设备已连接"); - // 清除显示标志 + // 清除显示标志并刷新UI _isDisplayingInfo = false; + UpdateImageOnUI(); // 清除错误信息 ShowError(string.Empty); From 8d62d8378ab7a72f49da8a092a4df04645a2ee51 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 10:43:01 +0800 Subject: [PATCH 36/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8DConnected=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 135110a..06b8ab8 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -808,13 +808,13 @@ namespace JoyD.Windows.CS.Toprie case ConnectionStatus.Connected: Console.WriteLine("设备已连接"); + // 清除错误信息 + ShowError(string.Empty); + // 清除显示标志并刷新UI _isDisplayingInfo = false; UpdateImageOnUI(); - // 清除错误信息 - ShowError(string.Empty); - // 仅在首次连接时设置为热图模式,重连时保留之前的模式 if (!_isReceivingImage) // 首次连接时_isReceivingImage为false { From 58705feec55967c67592f7f843f334b70e8f51b6 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 10:45:49 +0800 Subject: [PATCH 37/64] =?UTF-8?q?=E7=A7=BB=E9=99=A4Connected=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E4=B8=8B=E4=B8=8D=E5=BF=85=E8=A6=81=E7=9A=84ShowError?= =?UTF-8?q?(string.Empty)=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 06b8ab8..5d2d9fa 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -808,9 +808,6 @@ namespace JoyD.Windows.CS.Toprie case ConnectionStatus.Connected: Console.WriteLine("设备已连接"); - // 清除错误信息 - ShowError(string.Empty); - // 清除显示标志并刷新UI _isDisplayingInfo = false; UpdateImageOnUI(); From 27a95aa23997e113abe70de4cd446a0656b12689 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 11:05:08 +0800 Subject: [PATCH 38/64] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=9B=BE=E5=83=8F?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=B5=81=E7=A8=8B=EF=BC=9A=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=5FisPaused=E6=A0=87=E5=BF=97=E7=AE=A1=E7=90=86=E6=9A=82?= =?UTF-8?q?=E5=81=9C=E7=8A=B6=E6=80=81=EF=BC=8C=E7=BB=9F=E4=B8=80Info?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=80=BB=E8=BE=91=EF=BC=8C=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=AE=8C=E6=95=B4=E7=9A=84=E4=B8=89=E6=AD=A5=E7=BB=98=E5=88=B6?= =?UTF-8?q?=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 359 ++++++++---------- 1 file changed, 162 insertions(+), 197 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 5d2d9fa..21d2359 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -78,8 +78,96 @@ namespace JoyD.Windows.CS.Toprie Console.WriteLine($"相机控件设计模式状态已更新: {DesignMode}"); } + /// + /// 更新InfoImage显示 + /// 1. 如果断开,显示重连信息 + /// 2. 否则如果暂停,显示暂停信息 + /// 3. 最后调用更新UI + /// + private void UpdateInfo() + { + if (DesignMode) return; + + try + { + lock (_infoImageLock) + { + // 释放之前的InfoImage资源 + if (_infoImage != null) + { + try + { + _infoImage.Dispose(); + } + catch (Exception ex) + { + Console.WriteLine($"释放InfoImage资源异常: {ex.Message}"); + } + _infoImage = null; + } + + // 检查连接状态 + bool isDisconnected = _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Disconnected; + bool isReconnecting = _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Reconnecting; + bool isPaused = _isPaused; // 使用_isPaused标志判断暂停状态 + + // 如果需要显示信息,创建InfoImage + if (isDisconnected || isReconnecting || isPaused) + { + _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); + using (Graphics g = Graphics.FromImage(_infoImage)) + { + // 设置半透明背景 + using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black))) + { + g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); + } + + // 确定显示的文本和颜色 + string text = ""; + Color textColor = Color.White; + + if (isDisconnected || isReconnecting) + { + // 断开或重连状态 + text = isReconnecting ? "正在重连..." : "连接断开"; + textColor = isReconnecting ? Color.Yellow : Color.Red; + } + else if (isPaused) + { + // 暂停状态 + text = "暂停"; + textColor = Color.Red; + } + + // 绘制文本 + using (Font font = new Font("Arial", 48, FontStyle.Bold)) + using (SolidBrush textBrush = new SolidBrush(textColor)) + { + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + format.LineAlignment = StringAlignment.Center; + g.DrawString(text, font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format); + } + } + } + + // 设置显示标志 + _isDisplayingInfo = (isDisconnected || isReconnecting || isPaused); + } + + // 调用更新UI + UpdateImageOnUI(); + } + catch (Exception ex) + { + Console.WriteLine($"更新Info显示时出错: {ex.Message}"); + } + } + /// /// 暂停/恢复图像更新菜单项点击事件处理 + /// 1、暂停或恢复时,设置暂停状态,调用更新Info /// private void PauseImageUpdateToolStripMenuItem_Click(object sender, EventArgs e) { @@ -87,94 +175,47 @@ namespace JoyD.Windows.CS.Toprie try { - bool isPaused = pauseImageUpdateToolStripMenuItem.Text == "暂停图像更新"; + // 切换暂停状态 + _isPaused = !_isPaused; - if (isPaused) + if (_isPaused) { + // 设置暂停状态 pauseImageUpdateToolStripMenuItem.Text = "恢复图像更新"; - Console.WriteLine("图像更新已暂停"); - // 在InfoImage中绘制暂停字样 - lock (_infoImageLock) - { - // 释放之前的InfoImage资源 - if (_infoImage != null) - { - try - { - _infoImage.Dispose(); - } - catch (Exception ex) - { - Console.WriteLine($"释放InfoImage资源异常: {ex.Message}"); - } - } - - // 创建新的InfoImage并绘制暂停字样 - _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); - using (Graphics g = Graphics.FromImage(_infoImage)) - { - // 设置半透明背景 - using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black))) - { - g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); - } - - // 绘制暂停字样 - using (Font font = new Font("Arial", 48, FontStyle.Bold)) - using (SolidBrush textBrush = new SolidBrush(Color.Red)) - { - StringFormat format = new StringFormat(); - format.Alignment = StringAlignment.Center; - format.LineAlignment = StringAlignment.Center; - g.DrawString("暂停", font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format); - } - } - } - - // 设置显示信息标志并更新UI - _isDisplayingInfo = true; - UpdateImageOnUI(); - } - else - { - pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; - Console.WriteLine("图像更新已恢复"); - - // 清除InfoImage和显示标志 - lock (_infoImageLock) - { - if (_infoImage != null) - { - try - { - _infoImage.Dispose(); - _infoImage = null; - } - catch (Exception ex) - { - Console.WriteLine($"释放InfoImage资源异常: {ex.Message}"); - } - } - } - _isDisplayingInfo = false; - - // 立即更新UI - UpdateImageOnUI(); - - // 恢复时,立即停止并重新开始图像接收,确保获取最新图像 + // 暂停时停止图像接收 if (_isReceivingImage && _deviceManager != null) { _deviceManager.StopImageReceiving(); - _deviceManager.StartImageReceiving(); + _isReceivingImage = false; } + + Console.WriteLine("图像更新已暂停"); } + else + { + // 设置恢复状态 + pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; + + // 恢复时,立即停止并重新开始图像接收,确保获取最新图像 + if (_deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected) + { + _deviceManager.StopImageReceiving(); + _deviceManager.StartImageReceiving(); + _isReceivingImage = true; + } + + Console.WriteLine("图像更新已恢复"); + } + + // 按照用户要求:暂停或恢复时,设置暂停状态,调用更新Info + UpdateInfo(); } catch (Exception ex) { Console.WriteLine($"处理暂停/恢复图像更新时出错: {ex.Message}"); } - } + } public Camera() { @@ -428,84 +469,86 @@ namespace JoyD.Windows.CS.Toprie } } + private bool _isPaused = false; // 暂停状态标志 + /// /// 设备管理器图像接收事件处理 /// private void DeviceManager_ImageReceived(object sender, ImageReceivedEventArgs e) { - // 如果图像更新已暂停,则不更新UI - // 通过菜单项文本判断是否暂停 - if (pauseImageUpdateToolStripMenuItem.Text == "恢复图像更新") - return; if (DesignMode) return; try - { + { if (e.ImageData != null && e.ImageData.Length > 0) - { + { // 创建内存流并从流中创建图像 using (MemoryStream ms = new MemoryStream(e.ImageData)) - { + { // 检查流是否可读且有效 if (ms.CanRead && ms.Length > 0) - { + { // 从流中创建图像 using (Image tempImage = System.Drawing.Image.FromStream(ms)) - { + { // 创建一个全新的位图而仅仅是克隆,确保数据完整性 Image newImage = new Bitmap(tempImage); // 立即验证新创建的图像是否有效 try - { + { // 访问Width和Height属性来验证图像是否有效 int width = newImage.Width; int height = newImage.Height; if (width <= 0 || height <= 0) - { + { Console.WriteLine("创建的图像尺寸无效"); newImage.Dispose(); return; } } catch (Exception) - { + { Console.WriteLine("创建的图像无效"); newImage.Dispose(); return; } - // 按照用户要求:收到图像数据后,将图像保存到LastImage中,调用更新 + // 按照用户要求:收到图像数据后,将图像保存到LastImage中 lock (_lastImageLock) - { + { // 释放旧的LastImage资源 if (_lastImage != null) - { + { try { _lastImage.Dispose(); } catch {} } // 设置新的LastImage _lastImage = newImage; } - // 调用更新UI - this.BeginInvoke(new Action(() => - { - try - { - UpdateImageOnUI(); - } - catch (Exception ex) - { - Console.WriteLine($"更新UI图像失败: {ex.Message}"); - } - })); + // 按照用户要求:调用更新到UI + // 只有当图像更新未暂停时才更新UI + if (!_isPaused) + { + this.BeginInvoke(new Action(() => + { + try + { + UpdateImageOnUI(); + } + catch (Exception ex) + { + Console.WriteLine($"更新UI图像失败: {ex.Message}"); + } + })); + } } } } } } catch (Exception ex) - { + { Console.WriteLine($"处理接收到的图像时出错: {ex.Message}"); } } @@ -630,29 +673,6 @@ namespace JoyD.Windows.CS.Toprie g.DrawString("测试信息", font, textBrush, 10, 10); } } - - // 检查是否需要绘制暂停状态的mask信息 - bool isPaused = pauseImageUpdateToolStripMenuItem.Text == "恢复图像更新"; - if (isPaused) - { - // 绘制半透明黑色背景 - using (Brush brush = new SolidBrush(Color.FromArgb(100, Color.Black))) - { - g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); - } - - // 绘制"暂停"文字 - using (Font font = new Font("微软雅黑", 48, FontStyle.Bold)) - using (Brush textBrush = new SolidBrush(Color.White)) - { - StringFormat format = new StringFormat(); - format.Alignment = StringAlignment.Center; - format.LineAlignment = StringAlignment.Center; - - g.DrawString("暂停", font, textBrush, - new Rectangle(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format); - } - } } } @@ -780,6 +800,7 @@ namespace JoyD.Windows.CS.Toprie /// /// 处理连接状态变更 + /// 2、断开或连接时,设置连接状态,调用更新Info /// private void HandleConnectionStatusChanged(ConnectionStatusChangedEventArgs e) { @@ -808,10 +829,6 @@ namespace JoyD.Windows.CS.Toprie case ConnectionStatus.Connected: Console.WriteLine("设备已连接"); - // 清除显示标志并刷新UI - _isDisplayingInfo = false; - UpdateImageOnUI(); - // 仅在首次连接时设置为热图模式,重连时保留之前的模式 if (!_isReceivingImage) // 首次连接时_isReceivingImage为false { @@ -835,9 +852,19 @@ namespace JoyD.Windows.CS.Toprie // 开始接收图像(包含在try-catch中) if (!_isReceivingImage) - { - StartReceiveImage(); + { + try + { + StartReceiveImage(); + } + catch (Exception ex) + { + Console.WriteLine($"开始接收图像失败: {ex.Message}"); + } } + + // 设置连接状态后,调用更新Info + UpdateInfo(); break; case ConnectionStatus.Disconnected: Console.WriteLine("设备已断开连接"); @@ -857,39 +884,8 @@ namespace JoyD.Windows.CS.Toprie } } - // 在InfoImage中显示连接断开信息 - lock (_infoImageLock) - { - // 如果_infoImage为null,则创建新对象 - if (_infoImage == null) - { - _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); - } - - // 直接在现有InfoImage上重绘,不需要Dispose - using (Graphics g = Graphics.FromImage(_infoImage)) - { - // 设置半透明背景 - using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black))) - { - g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); - } - - // 绘制断开连接字样 - using (Font font = new Font("Arial", 36, FontStyle.Bold)) - using (SolidBrush textBrush = new SolidBrush(Color.Red)) - { - StringFormat format = new StringFormat(); - format.Alignment = StringAlignment.Center; - format.LineAlignment = StringAlignment.Center; - g.DrawString("连接断开", font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format); - } - } - } - - // 设置显示信息标志并更新UI - _isDisplayingInfo = true; - UpdateImageOnUI(); + // 设置连接状态后,调用更新Info + UpdateInfo(); if (!string.IsNullOrEmpty(e.DeviceInfo)) { @@ -908,39 +904,8 @@ namespace JoyD.Windows.CS.Toprie Console.WriteLine($"正在重新连接设备...{(!string.IsNullOrEmpty(e.DeviceInfo) ? " " + e.DeviceInfo : "")}"); ShowError(string.Empty); // 清除之前的错误信息 - // 在InfoImage中显示正在重连信息 - lock (_infoImageLock) - { - // 如果_infoImage为null,则创建新对象 - if (_infoImage == null) - { - _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); - } - - // 直接在现有InfoImage上重绘,不需要Dispose - using (Graphics g = Graphics.FromImage(_infoImage)) - { - // 设置半透明背景 - using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black))) - { - g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); - } - - // 绘制正在重连字样 - using (Font font = new Font("Arial", 36, FontStyle.Bold)) - using (SolidBrush textBrush = new SolidBrush(Color.Yellow)) - { - StringFormat format = new StringFormat(); - format.Alignment = StringAlignment.Center; - format.LineAlignment = StringAlignment.Center; - g.DrawString("正在重连...", font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format); - } - } - } - - // 设置显示信息标志并更新UI - _isDisplayingInfo = true; - UpdateImageOnUI(); + // 设置重连状态后,调用更新Info + UpdateInfo(); break; } } From 2ff93d44b9ccf9ef73d41102e3d46fb731527489 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 11:06:58 +0800 Subject: [PATCH 39/64] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E8=A6=81=E6=B1=82?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=9A=E7=A8=8B=E5=BA=8F=E9=80=80=E5=87=BA?= =?UTF-8?q?=E5=89=8D=E4=B8=8D=E9=9C=80=E8=A6=81=E5=AF=B9LastImage=E3=80=81?= =?UTF-8?q?InfoImage=E5=92=8Cimagebuffer=E6=89=A7=E8=A1=8CDispose=E5=92=8C?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E4=B8=BAnull?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 53 ++----------------- 1 file changed, 3 insertions(+), 50 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 21d2359..81f08f5 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -1512,56 +1512,9 @@ namespace JoyD.Windows.CS.Toprie imageBox.Image = null; } - // 释放图像缓冲区资源 - if (_imageBuffer != null) - { - try - { - _imageBuffer.Dispose(); - _imageBuffer = null; - Console.WriteLine("图像缓冲区资源已释放"); - } - catch (Exception ex) - { - Console.WriteLine($"清理ImageBuffer资源异常: {ex.Message}"); - } - } - - // 释放LastImage资源 - lock (_lastImageLock) - { - if (_lastImage != null) - { - try - { - _lastImage.Dispose(); - _lastImage = null; - Console.WriteLine("LastImage资源已释放"); - } - catch (Exception ex) - { - Console.WriteLine($"清理LastImage资源异常: {ex.Message}"); - } - } - } - - // 释放InfoImage资源 - lock (_infoImageLock) - { - if (_infoImage != null) - { - try - { - _infoImage.Dispose(); - _infoImage = null; - Console.WriteLine("InfoImage资源已释放"); - } - catch (Exception ex) - { - Console.WriteLine($"清理InfoImage资源异常: {ex.Message}"); - } - } - } + // 注意:根据要求,在程序退出前不需要对LastImage、InfoImage和imagebuffer执行Dispose和设置为null + // 保留注释以表明设计意图 + // 这些资源将由垃圾回收器自动管理 // 释放组件资源 if (components != null) From 123789a6075b7a704e304a9cad4e729456cb97b9 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 11:09:01 +0800 Subject: [PATCH 40/64] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E5=AF=B9LastImage?= =?UTF-8?q?=E3=80=81InfoImage=E5=92=8Cimagebuffer=E7=9A=84Dispose=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E5=92=8C=E8=AE=BE=E4=B8=BAnull?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 81f08f5..21d2359 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -1512,9 +1512,56 @@ namespace JoyD.Windows.CS.Toprie imageBox.Image = null; } - // 注意:根据要求,在程序退出前不需要对LastImage、InfoImage和imagebuffer执行Dispose和设置为null - // 保留注释以表明设计意图 - // 这些资源将由垃圾回收器自动管理 + // 释放图像缓冲区资源 + if (_imageBuffer != null) + { + try + { + _imageBuffer.Dispose(); + _imageBuffer = null; + Console.WriteLine("图像缓冲区资源已释放"); + } + catch (Exception ex) + { + Console.WriteLine($"清理ImageBuffer资源异常: {ex.Message}"); + } + } + + // 释放LastImage资源 + lock (_lastImageLock) + { + if (_lastImage != null) + { + try + { + _lastImage.Dispose(); + _lastImage = null; + Console.WriteLine("LastImage资源已释放"); + } + catch (Exception ex) + { + Console.WriteLine($"清理LastImage资源异常: {ex.Message}"); + } + } + } + + // 释放InfoImage资源 + lock (_infoImageLock) + { + if (_infoImage != null) + { + try + { + _infoImage.Dispose(); + _infoImage = null; + Console.WriteLine("InfoImage资源已释放"); + } + catch (Exception ex) + { + Console.WriteLine($"清理InfoImage资源异常: {ex.Message}"); + } + } + } // 释放组件资源 if (components != null) From 5653e3bcdc66d82a056702a9f61edbcd396c6ce4 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 13:27:25 +0800 Subject: [PATCH 41/64] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AE=BE=E5=A4=87Ping?= =?UTF-8?q?=E9=97=B4=E9=9A=94=E6=97=B6=E9=97=B4=E4=B8=BA=E6=AF=8F0.5?= =?UTF-8?q?=E7=A7=92=E4=B8=80=E6=AC=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 272 +++++++++++------- 1 file changed, 174 insertions(+), 98 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 21d2359..8130c97 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -67,7 +67,7 @@ namespace JoyD.Windows.CS.Toprie } // 显示错误的定时器 - private System.Windows.Forms.Timer _errorDisplayTimer; + /// /// 更新设计模式状态到DeviceManager @@ -85,7 +85,9 @@ namespace JoyD.Windows.CS.Toprie /// 3. 最后调用更新UI /// private void UpdateInfo() - { + { + // 更新Ping状态到Info文本 + Console.WriteLine($"Ping状态更新: {(IsDevicePingable ? "可Ping通" : "不可Ping通")}"); if (DesignMode) return; try @@ -128,17 +130,21 @@ namespace JoyD.Windows.CS.Toprie Color textColor = Color.White; if (isDisconnected || isReconnecting) - { + { // 断开或重连状态 text = isReconnecting ? "正在重连..." : "连接断开"; textColor = isReconnecting ? Color.Yellow : Color.Red; } else if (isPaused) - { + { // 暂停状态 text = "暂停"; textColor = Color.Red; } + // 添加Ping状态信息 + string pingStatus = IsDevicePingable ? "Ping通" : "Ping不通"; + string pingText = $"设备{pingStatus}"; + Color pingColor = IsDevicePingable ? Color.Green : Color.Red; // 绘制文本 using (Font font = new Font("Arial", 48, FontStyle.Bold)) @@ -146,8 +152,24 @@ namespace JoyD.Windows.CS.Toprie { StringFormat format = new StringFormat(); format.Alignment = StringAlignment.Center; - format.LineAlignment = StringAlignment.Center; - g.DrawString(text, font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format); + + // 将主文本位置调整到上方 + g.DrawString(text, font, textBrush, + new RectangleF(0, BUFFER_HEIGHT / 4, BUFFER_WIDTH, BUFFER_HEIGHT / 3), + format); + } + + // 绘制Ping状态信息 + using (Font pingFont = new Font("Arial", 36, FontStyle.Regular)) + using (SolidBrush pingBrush = new SolidBrush(pingColor)) + { + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + + // 将Ping状态文本位置放在主文本下方 + g.DrawString(pingText, pingFont, pingBrush, + new RectangleF(0, BUFFER_HEIGHT * 2 / 3, BUFFER_WIDTH, BUFFER_HEIGHT / 3), + format); } } } @@ -230,6 +252,9 @@ namespace JoyD.Windows.CS.Toprie // 初始化图像缓冲区 InitializeImageBuffer(); + // 初始化Ping定时器 + _pingTimer = new System.Threading.Timer(PingTimer_Tick, null, Timeout.Infinite, Timeout.Infinite); + // 只有在非设计模式下才初始化设备管理器和错误定时器 if (!DesignMode) { @@ -251,7 +276,6 @@ namespace JoyD.Windows.CS.Toprie catch { } InitializeDeviceManager(); - InitializeErrorTimer(); } } @@ -331,20 +355,15 @@ namespace JoyD.Windows.CS.Toprie } } - /// - /// 初始化错误显示定时器 - /// - private void InitializeErrorTimer() - { - _errorDisplayTimer = new System.Windows.Forms.Timer { Interval = 3000 }; // 显示3秒后清除 - _errorDisplayTimer.Tick += ErrorDisplayTimer_Tick; - } + /// /// 启动相机 /// public void StartCamera() - { + { + // 启动设备Ping + StartDevicePing(); if (DesignMode) return; try { @@ -453,7 +472,9 @@ namespace JoyD.Windows.CS.Toprie /// 停止接收图像 /// public void StopCamera() - { + { + // 停止设备Ping + StopDevicePing(); if (DesignMode) return; try { @@ -471,6 +492,29 @@ namespace JoyD.Windows.CS.Toprie private bool _isPaused = false; // 暂停状态标志 + // Ping相关字段 + private System.Threading.Timer _pingTimer; + private bool _isDevicePingable = false; + private const int _pingInterval = 500; // 0.5秒Ping一次 + + /// + /// 获取设备是否可Ping通 + /// + public bool IsDevicePingable + { + get { return _isDevicePingable; } + private set + { + if (_isDevicePingable != value) + { + _isDevicePingable = value; + Console.WriteLine($"设备Ping状态变更: {(_isDevicePingable ? "可Ping通" : "不可Ping通")}"); + // 状态变化时调用更新Info + UpdateInfo(); + } + } + } + /// /// 设备管理器图像接收事件处理 /// @@ -1069,82 +1113,9 @@ namespace JoyD.Windows.CS.Toprie { if (DesignMode) return; Console.WriteLine(message); - - // 可以根据需要添加UI上的错误显示 - // 这里简化处理,只在控制台输出 - - // 检查imageBox是否存在且尺寸有效 - if (imageBox == null || imageBox.Width <= 0 || imageBox.Height <= 0) - { - Console.WriteLine("imageBox尺寸无效,跳过错误显示图像创建"); - return; - } - - // 确保使用有效的尺寸创建Bitmap - int width = Math.Max(100, imageBox.Width); - int height = Math.Max(100, imageBox.Height); - - // 如果需要在图像区域显示错误文字,可以使用以下代码 - using (Bitmap errorBitmap = new Bitmap(width, height)) - using (Graphics g = Graphics.FromImage(errorBitmap)) - { - g.Clear(Color.Black); - using (Font font = new Font("Arial", 10)) - using (Brush brush = new SolidBrush(Color.Red)) - { - SizeF textSize = g.MeasureString(message, font); - PointF textLocation = new PointF( - (errorBitmap.Width - textSize.Width) / 2, - (errorBitmap.Height - textSize.Height) / 2); - g.DrawString(message, font, brush, textLocation); - } - - UpdateImageOnUI(errorBitmap); - } - - // 启动定时器,3秒后清除错误显示 - _errorDisplayTimer.Stop(); - _errorDisplayTimer.Start(); + // 错误消息仅写入日志即可,不需要在UI上显示 } - /// - /// 错误显示定时器事件 - /// - private void ErrorDisplayTimer_Tick(object sender, EventArgs e) - { - if (DesignMode) return; - _errorDisplayTimer.Stop(); - // 清除错误显示,恢复到等待图像状态 - - // 检查imageBox是否存在且尺寸有效 - if (imageBox == null || imageBox.Width <= 0 || imageBox.Height <= 0) - { - Console.WriteLine("imageBox尺寸无效,跳过等待图像创建"); - return; - } - - // 确保使用有效的尺寸创建Bitmap - int width = Math.Max(100, imageBox.Width); - int height = Math.Max(100, imageBox.Height); - - using (Bitmap waitingBitmap = new Bitmap(width, height)) - using (Graphics g = Graphics.FromImage(waitingBitmap)) - { - g.Clear(Color.Black); - using (Font font = new Font("Arial", 10)) - using (Brush brush = new SolidBrush(Color.White)) - { - string waitingText = "正在等待热图数据..."; - SizeF textSize = g.MeasureString(waitingText, font); - PointF textLocation = new PointF( - (waitingBitmap.Width - textSize.Width) / 2, - (waitingBitmap.Height - textSize.Height) / 2); - g.DrawString(waitingText, font, brush, textLocation); - } - - UpdateImageOnUI(waitingBitmap); - } - } /// /// 右键菜单显示前的事件处理方法 @@ -1463,6 +1434,110 @@ namespace JoyD.Windows.CS.Toprie #endregion + #region 设备Ping相关方法 + + /// + /// Ping定时器的回调方法 + /// + /// 状态对象 + private void PingTimer_Tick(object state) + { + if (_deviceManager != null && !string.IsNullOrEmpty(_deviceManager.IPAddress)) + { + Task.Run(() => + { + bool pingResult = PingDevice(_deviceManager.IPAddress); + try + { + // 在线程安全的方式下更新状态 + if (this.InvokeRequired) + { + this.Invoke(new Action(UpdatePingState), pingResult); + } + else + { + UpdatePingState(pingResult); + } + } + catch (ObjectDisposedException) + { + // 控件可能已被释放,忽略此更新 + } + }); + } + } + + /// + /// 执行Ping操作 + /// + /// 要Ping的IP地址 + /// 是否Ping通 + private bool PingDevice(string ipAddress) + { + try + { + using (var ping = new System.Net.NetworkInformation.Ping()) + { + var reply = ping.Send(ipAddress, 2000); // 2秒超时 + return reply != null && reply.Status == System.Net.NetworkInformation.IPStatus.Success; + } + } + catch (Exception ex) + { + Console.WriteLine($"Ping设备失败: {ex.Message}"); + return false; + } + } + + /// + /// 更新Ping状态 + /// + /// 是否可Ping通 + private void UpdatePingState(bool isPingable) + { + IsDevicePingable = isPingable; + } + + /// + /// 开始设备Ping + /// + private void StartDevicePing() + { + try + { + if (_pingTimer != null) + { + _pingTimer.Change(0, _pingInterval); // 立即开始,然后按间隔执行 + Console.WriteLine("设备Ping已启动"); + } + } + catch (Exception ex) + { + Console.WriteLine($"启动设备Ping失败: {ex.Message}"); + } + } + + /// + /// 停止设备Ping + /// + private void StopDevicePing() + { + try + { + if (_pingTimer != null) + { + _pingTimer.Change(Timeout.Infinite, Timeout.Infinite); + Console.WriteLine("设备Ping已停止"); + } + } + catch (Exception ex) + { + Console.WriteLine($"停止设备Ping失败: {ex.Message}"); + } + } + + #endregion + /// /// 清理资源 /// @@ -1497,15 +1572,16 @@ namespace JoyD.Windows.CS.Toprie _deviceManager = null; } - // 无论是否在设计模式下,都需要释放定时器 - if (_errorDisplayTimer != null) - { - _errorDisplayTimer.Stop(); - _errorDisplayTimer.Dispose(); - _errorDisplayTimer = null; - } + // 无论是否在设计模式下,都需要释放图像资源 + + // 释放Ping定时器 + if (_pingTimer != null) + { + _pingTimer.Dispose(); + _pingTimer = null; + } if (imageBox != null && !imageBox.IsDisposed && imageBox.Image != null) { imageBox.Image.Dispose(); From fe4f3f564f099508ec700f76c01917317ca24ac1 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 13:28:27 +0800 Subject: [PATCH 42/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8DTask=E7=B1=BB=E6=9C=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E7=9A=84=E7=BC=96=E8=AF=91=E9=94=99=E8=AF=AF?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0System.Threading.Tasks=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E7=A9=BA=E9=97=B4=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 8130c97..472fffd 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; +using System.Threading.Tasks; namespace JoyD.Windows.CS.Toprie { From 816975753e1fc701ab8400640c1bdb7f73295c4f Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 13:30:14 +0800 Subject: [PATCH 43/64] =?UTF-8?q?=E5=B0=86Task.Run=E6=9B=BF=E6=8D=A2?= =?UTF-8?q?=E4=B8=BATask.Factory.StartNew=E4=BB=A5=E5=85=BC=E5=AE=B9.NET?= =?UTF-8?q?=20Framework=204.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 472fffd..f5f23ff 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -1445,7 +1445,7 @@ namespace JoyD.Windows.CS.Toprie { if (_deviceManager != null && !string.IsNullOrEmpty(_deviceManager.IPAddress)) { - Task.Run(() => + Task.Factory.StartNew(() => { bool pingResult = PingDevice(_deviceManager.IPAddress); try From 8f8c32879ddf41fe63dd5740b1c536b1cd41c7f1 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 13:33:51 +0800 Subject: [PATCH 44/64] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E7=9A=84UpdateImageOnUI(Image=20image)?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index f5f23ff..198ad56 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -598,13 +598,7 @@ namespace JoyD.Windows.CS.Toprie } } - /// - /// 在UI线程上更新图像 - /// - private void UpdateImageOnUI(Image image) // 保留原有方法签名,处理旧调用 - { - UpdateImageOnUI(); - } + /// /// 在UI线程上更新图像 - 新实现,按照用户要求: From 2c51fe83f4c9dd7ff09e32e36d48e3912660e33c Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 13:36:59 +0800 Subject: [PATCH 45/64] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=92=8C=E5=9B=BE=E5=83=8F=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=EF=BC=8C=E6=8C=89=E7=85=A7=E8=A7=84=E8=8C=83?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=8A=B6=E6=80=81=E5=8F=98=E6=9B=B4=E5=92=8C?= =?UTF-8?q?UI=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 57 +++++++++---------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 198ad56..4e0a24c 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -113,9 +113,10 @@ namespace JoyD.Windows.CS.Toprie bool isDisconnected = _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Disconnected; bool isReconnecting = _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Reconnecting; bool isPaused = _isPaused; // 使用_isPaused标志判断暂停状态 + bool isPingFailed = !IsDevicePingable; // 如果需要显示信息,创建InfoImage - if (isDisconnected || isReconnecting || isPaused) + if (isDisconnected || isReconnecting || isPaused || isPingFailed) { _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); using (Graphics g = Graphics.FromImage(_infoImage)) @@ -130,11 +131,25 @@ namespace JoyD.Windows.CS.Toprie string text = ""; Color textColor = Color.White; - if (isDisconnected || isReconnecting) + // 根据要求的优先级显示信息:先检查Ping状态和连接状态,最后检查暂停状态 + if (isPingFailed || isDisconnected || isReconnecting) { - // 断开或重连状态 - text = isReconnecting ? "正在重连..." : "连接断开"; - textColor = isReconnecting ? Color.Yellow : Color.Red; + // Ping不通或断开连接状态 + if (isReconnecting) + { + text = "正在重连..."; + textColor = Color.Yellow; + } + else if (isDisconnected) + { + text = "连接断开"; + textColor = Color.Red; + } + else if (isPingFailed) + { + text = "Ping不通"; + textColor = Color.Red; + } } else if (isPaused) { @@ -142,10 +157,6 @@ namespace JoyD.Windows.CS.Toprie text = "暂停"; textColor = Color.Red; } - // 添加Ping状态信息 - string pingStatus = IsDevicePingable ? "Ping通" : "Ping不通"; - string pingText = $"设备{pingStatus}"; - Color pingColor = IsDevicePingable ? Color.Green : Color.Red; // 绘制文本 using (Font font = new Font("Arial", 48, FontStyle.Bold)) @@ -154,22 +165,9 @@ namespace JoyD.Windows.CS.Toprie StringFormat format = new StringFormat(); format.Alignment = StringAlignment.Center; - // 将主文本位置调整到上方 + // 将主文本居中显示 g.DrawString(text, font, textBrush, - new RectangleF(0, BUFFER_HEIGHT / 4, BUFFER_WIDTH, BUFFER_HEIGHT / 3), - format); - } - - // 绘制Ping状态信息 - using (Font pingFont = new Font("Arial", 36, FontStyle.Regular)) - using (SolidBrush pingBrush = new SolidBrush(pingColor)) - { - StringFormat format = new StringFormat(); - format.Alignment = StringAlignment.Center; - - // 将Ping状态文本位置放在主文本下方 - g.DrawString(pingText, pingFont, pingBrush, - new RectangleF(0, BUFFER_HEIGHT * 2 / 3, BUFFER_WIDTH, BUFFER_HEIGHT / 3), + new RectangleF(0, BUFFER_HEIGHT / 3, BUFFER_WIDTH, BUFFER_HEIGHT / 3), format); } } @@ -630,12 +628,8 @@ namespace JoyD.Windows.CS.Toprie try { - // 连接状态检查 - 只在设备实际连接时处理图像 - if (_deviceManager.ConnectionStatus != ConnectionStatus.Connected) - { - Console.WriteLine("设备未连接,跳过图像更新"); - return; - } + // 移除连接状态检查,确保在任何状态下都能更新UI + // 根据流程要求,需要在断开或Ping不通时也能显示相关信息 // 检查图像缓冲区是否有效 if (_imageBuffer == null) @@ -868,6 +862,9 @@ namespace JoyD.Windows.CS.Toprie case ConnectionStatus.Connected: Console.WriteLine("设备已连接"); + // 连接时调用更新Info + UpdateInfo(); + // 仅在首次连接时设置为热图模式,重连时保留之前的模式 if (!_isReceivingImage) // 首次连接时_isReceivingImage为false { From 60fc9138ecff25b52b7855498bd3608ec3fbe8fe Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 13:39:42 +0800 Subject: [PATCH 46/64] =?UTF-8?q?=E6=B8=85=E7=90=86Connected=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E4=B8=8B=E9=87=8D=E5=A4=8D=E7=9A=84UpdateInfo?= =?UTF-8?q?=E8=B0=83=E7=94=A8=EF=BC=8C=E4=BC=98=E5=8C=96=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 4e0a24c..a16152f 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -862,9 +862,6 @@ namespace JoyD.Windows.CS.Toprie case ConnectionStatus.Connected: Console.WriteLine("设备已连接"); - // 连接时调用更新Info - UpdateInfo(); - // 仅在首次连接时设置为热图模式,重连时保留之前的模式 if (!_isReceivingImage) // 首次连接时_isReceivingImage为false { @@ -888,13 +885,13 @@ namespace JoyD.Windows.CS.Toprie // 开始接收图像(包含在try-catch中) if (!_isReceivingImage) - { + { try - { + { StartReceiveImage(); } catch (Exception ex) - { + { Console.WriteLine($"开始接收图像失败: {ex.Message}"); } } From 8b7b7247bdd025925be1b149833471c5c2d13932 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 13:42:31 +0800 Subject: [PATCH 47/64] =?UTF-8?q?=E5=B0=86Ping=E4=B8=8D=E9=80=9A=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=96=87=E6=9C=AC=E4=BF=AE=E6=94=B9=E4=B8=BA=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E6=96=AD=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index a16152f..5e8c5e3 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -147,7 +147,7 @@ namespace JoyD.Windows.CS.Toprie } else if (isPingFailed) { - text = "Ping不通"; + text = "连接断开"; textColor = Color.Red; } } From 5721af8aaae202e5db696f37273a1bec02633ce6 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 14:15:24 +0800 Subject: [PATCH 48/64] =?UTF-8?q?=E6=9B=B4=E6=96=B0Toprie=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=EF=BC=9A=E5=B0=86=E6=9A=82=E5=81=9C=E5=9B=BE=E5=83=8F?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8A=9F=E8=83=BD=E6=94=B9=E4=B8=BA=E6=9A=82?= =?UTF-8?q?=E5=81=9C=E6=A3=80=E6=B5=8B=EF=BC=8C=E7=A7=BB=E9=99=A4mask?= =?UTF-8?q?=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Toprie/Toprie/Camera.Designer.cs | 38 +++++-------------- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 16 ++++---- 2 files changed, 17 insertions(+), 37 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs index 3a72337..49d6ec0 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.Designer.cs @@ -17,7 +17,6 @@ namespace JoyD.Windows.CS.Toprie { this.components = new System.ComponentModel.Container(); this.imageBox = new System.Windows.Forms.PictureBox(); - this.maskImageBox = new System.Windows.Forms.PictureBox(); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.imageModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.thermalModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -37,7 +36,7 @@ namespace JoyD.Windows.CS.Toprie this.redHotToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.rainbow2ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.pauseImageUpdateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.pauseDetectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.imageBox)).BeginInit(); this.contextMenuStrip1.SuspendLayout(); this.SuspendLayout(); @@ -53,26 +52,13 @@ namespace JoyD.Windows.CS.Toprie this.imageBox.TabIndex = 0; this.imageBox.TabStop = false; // - // maskImageBox - // - this.maskImageBox.ContextMenuStrip = this.contextMenuStrip1; - this.maskImageBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.maskImageBox.Location = new System.Drawing.Point(0, 0); - this.maskImageBox.Name = "maskImageBox"; - this.maskImageBox.Size = new System.Drawing.Size(512, 384); - this.maskImageBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; - this.maskImageBox.TabIndex = 1; - this.maskImageBox.TabStop = false; - this.maskImageBox.BackColor = System.Drawing.Color.Transparent; - this.maskImageBox.Visible = true; - // // contextMenuStrip1 // this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.imageModeToolStripMenuItem, this.colorModeToolStripMenuItem, this.toolStripSeparator1, - this.pauseImageUpdateToolStripMenuItem}); + this.pauseDetectionToolStripMenuItem}); this.contextMenuStrip1.Name = "contextMenuStrip1"; this.contextMenuStrip1.Size = new System.Drawing.Size(161, 100); // @@ -116,12 +102,12 @@ namespace JoyD.Windows.CS.Toprie this.toolStripSeparator1.Name = "toolStripSeparator1"; this.toolStripSeparator1.Size = new System.Drawing.Size(157, 6); // - // pauseImageUpdateToolStripMenuItem + // pauseDetectionToolStripMenuItem // - this.pauseImageUpdateToolStripMenuItem.Name = "pauseImageUpdateToolStripMenuItem"; - this.pauseImageUpdateToolStripMenuItem.Size = new System.Drawing.Size(160, 22); - this.pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; - this.pauseImageUpdateToolStripMenuItem.Click += new System.EventHandler(this.PauseImageUpdateToolStripMenuItem_Click); + this.pauseDetectionToolStripMenuItem.Name = "pauseDetectionToolStripMenuItem"; + this.pauseDetectionToolStripMenuItem.Size = new System.Drawing.Size(160, 22); + this.pauseDetectionToolStripMenuItem.Text = "暂停检测"; + this.pauseDetectionToolStripMenuItem.Click += new System.EventHandler(this.PauseDetectionToolStripMenuItem_Click); this.colorModeToolStripMenuItem.Name = "colorModeToolStripMenuItem"; this.colorModeToolStripMenuItem.Size = new System.Drawing.Size(160, 22); this.colorModeToolStripMenuItem.Text = "色彩模式"; @@ -188,17 +174,12 @@ namespace JoyD.Windows.CS.Toprie // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - // 先添加imageBox基础层 + // 添加imageBox this.Controls.Add(this.imageBox); - // 再添加maskImageBox遮罩层,确保它显示在上面 - this.Controls.Add(this.maskImageBox); - // 确保maskImageBox显示在顶层 - this.maskImageBox.BringToFront(); this.Name = "Camera"; this.Size = new System.Drawing.Size(512, 384); this.Load += new System.EventHandler(this.Camera_Load); ((System.ComponentModel.ISupportInitialize)(this.imageBox)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.maskImageBox)).EndInit(); this.contextMenuStrip1.ResumeLayout(false); this.ResumeLayout(false); @@ -207,9 +188,8 @@ namespace JoyD.Windows.CS.Toprie #endregion private System.Windows.Forms.PictureBox imageBox; - private System.Windows.Forms.PictureBox maskImageBox; private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; - private System.Windows.Forms.ToolStripMenuItem pauseImageUpdateToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem pauseDetectionToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; private System.Windows.Forms.ToolStripMenuItem colorModeToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem whiteHotToolStripMenuItem; diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 5e8c5e3..ba54310 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -187,10 +187,10 @@ namespace JoyD.Windows.CS.Toprie } /// - /// 暂停/恢复图像更新菜单项点击事件处理 + /// 暂停/恢复检测菜单项点击事件处理 /// 1、暂停或恢复时,设置暂停状态,调用更新Info /// - private void PauseImageUpdateToolStripMenuItem_Click(object sender, EventArgs e) + private void PauseDetectionToolStripMenuItem_Click(object sender, EventArgs e) { if (DesignMode) return; @@ -202,7 +202,7 @@ namespace JoyD.Windows.CS.Toprie if (_isPaused) { // 设置暂停状态 - pauseImageUpdateToolStripMenuItem.Text = "恢复图像更新"; + pauseDetectionToolStripMenuItem.Text = "恢复检测"; // 暂停时停止图像接收 if (_isReceivingImage && _deviceManager != null) @@ -211,12 +211,12 @@ namespace JoyD.Windows.CS.Toprie _isReceivingImage = false; } - Console.WriteLine("图像更新已暂停"); + Console.WriteLine("检测已暂停"); } else { // 设置恢复状态 - pauseImageUpdateToolStripMenuItem.Text = "暂停图像更新"; + pauseDetectionToolStripMenuItem.Text = "暂停检测"; // 恢复时,立即停止并重新开始图像接收,确保获取最新图像 if (_deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected) @@ -226,7 +226,7 @@ namespace JoyD.Windows.CS.Toprie _isReceivingImage = true; } - Console.WriteLine("图像更新已恢复"); + Console.WriteLine("检测已恢复"); } // 按照用户要求:暂停或恢复时,设置暂停状态,调用更新Info @@ -234,7 +234,7 @@ namespace JoyD.Windows.CS.Toprie } catch (Exception ex) { - Console.WriteLine($"处理暂停/恢复图像更新时出错: {ex.Message}"); + Console.WriteLine($"处理暂停/恢复检测时出错: {ex.Message}"); } } @@ -1120,7 +1120,7 @@ namespace JoyD.Windows.CS.Toprie try { // 检查是否处于暂停状态 - bool isPaused = pauseImageUpdateToolStripMenuItem.Text == "恢复图像更新"; + bool isPaused = pauseDetectionToolStripMenuItem.Text == "恢复检测"; // 在暂停状态下,隐藏图像模式根菜单和色彩模式菜单 // 注意:根菜单隐藏后,其所有子菜单会自动隐藏,不需要单独设置 From a88d63a430433a219f295b33367a8ee55351afda Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 14:26:12 +0800 Subject: [PATCH 49/64] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f0e9b72..71b9659 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,15 @@ # JoyD -久鼎代码库 \ No newline at end of file +久鼎代码库 +### 修改流程: + 1. 暂停或恢复时,设置暂停状态,调用更新Info + 2. 断开或连接时,设置连接状态,调用更新Info + 3. Ping通状态变化时,修改Ping状态,调用更新Info + 4. 图像更新时, 保存LastImage, 调用更新到UI + ### 更新Info: + 1. 如果暂停,显示暂停信息,否则如果Ping不通或断开,显示重连信息,否则清空InfoImage + 2. 最后调用更新UI + ### 更新UI: + 1. 先将LastImage绘制到全局缓冲 + 2. 再将InfoImage绘制到缓冲 + 3. 最后一次性绘制到图像框的bitmap \ No newline at end of file From 5a6172d5419667ee552156257aacea580db2dd0d Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 14:35:28 +0800 Subject: [PATCH 50/64] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=9A=82=E5=81=9C?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E6=97=B6=E4=B8=8D=E8=BF=9B=E8=A1=8C=E9=87=8D?= =?UTF-8?q?=E8=BF=9E=E6=93=8D=E4=BD=9C=E5=92=8C=E8=BF=9E=E6=8E=A5=E6=A3=80?= =?UTF-8?q?=E6=B5=8B=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 36 +++++++++---- .../Toprie/Toprie/DeviceManager.cs | 54 +++++++++++++++---- 2 files changed, 70 insertions(+), 20 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index ba54310..1868c84 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -204,11 +204,16 @@ namespace JoyD.Windows.CS.Toprie // 设置暂停状态 pauseDetectionToolStripMenuItem.Text = "恢复检测"; - // 暂停时停止图像接收 - if (_isReceivingImage && _deviceManager != null) + // 暂停时停止图像接收并更新DeviceManager的暂停检测状态 + if (_deviceManager != null) { - _deviceManager.StopImageReceiving(); - _isReceivingImage = false; + _deviceManager.IsDetectionPaused = true; + + if (_isReceivingImage) + { + _deviceManager.StopImageReceiving(); + _isReceivingImage = false; + } } Console.WriteLine("检测已暂停"); @@ -218,12 +223,25 @@ namespace JoyD.Windows.CS.Toprie // 设置恢复状态 pauseDetectionToolStripMenuItem.Text = "暂停检测"; - // 恢复时,立即停止并重新开始图像接收,确保获取最新图像 - if (_deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected) + // 恢复时更新DeviceManager的暂停检测状态并重新开始图像接收 + if (_deviceManager != null) { - _deviceManager.StopImageReceiving(); - _deviceManager.StartImageReceiving(); - _isReceivingImage = true; + _deviceManager.IsDetectionPaused = false; + + if (_deviceManager.ConnectionStatus == ConnectionStatus.Connected) + { + _deviceManager.StopImageReceiving(); + _deviceManager.StartImageReceiving(); + _isReceivingImage = true; + + // 恢复检测后,启动连接检查以确保连接正常 + _deviceManager.StartConnectionCheck(); + } + // 如果当前是断开状态但启用了自动重连,尝试启动重连 + else if (_deviceManager.AutoReconnectEnabled) + { + _deviceManager.StartAutoReconnect(); + } } Console.WriteLine("检测已恢复"); diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index 00b1af8..9eda918 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -153,6 +153,9 @@ namespace JoyD.Windows.CS.Toprie // 设计模式标志,用于在设计模式下跳过实际的设备连接和初始化 public static bool IsDesignMode { get; set; } = true; + // 暂停检测标志,用于控制是否进行连接检测和重连操作 + public bool IsDetectionPaused { get; set; } = false; + // 项目路径,用于数据文件的存取 private string _projectPath = ""; @@ -185,7 +188,6 @@ namespace JoyD.Windows.CS.Toprie // 当前视频模式 private VideoMode _currentVideoMode = VideoMode.Infrared; // 默认红外模式 // 自动重连是否启用 - private readonly bool _autoReconnectEnabled = true; // 自动重连定时器 private System.Threading.Timer _reconnectTimer; // 重连间隔(毫秒) @@ -378,7 +380,7 @@ namespace JoyD.Windows.CS.Toprie // 保存状态变更相关信息供后续处理 ConnectionStatus finalNewStatus = newStatus; - bool shouldReconnect = (newStatus == ConnectionStatus.Disconnected && _autoReconnectEnabled && oldStatus != ConnectionStatus.Connecting); + bool shouldReconnect = (newStatus == ConnectionStatus.Disconnected && _isAutoReconnectEnabled && oldStatus != ConnectionStatus.Connecting); bool shouldReset = (newStatus == ConnectionStatus.Connected); // 添加状态转换验证,避免不合理的状态切换 @@ -866,7 +868,7 @@ namespace JoyD.Windows.CS.Toprie /// /// 启动连接状态检查 /// - private void StartConnectionCheck() + public void StartConnectionCheck() { lock (_lockObject) // 添加线程同步锁 { @@ -879,6 +881,13 @@ namespace JoyD.Windows.CS.Toprie return; } + // 在暂停检测模式下,跳过连接检查 + if (IsDetectionPaused) + { + Log("暂停检测模式下跳过连接检查"); + return; + } + // 首先停止现有的连接检查,确保资源释放 StopConnectionCheck(); @@ -925,7 +934,7 @@ namespace JoyD.Windows.CS.Toprie Log("重新初始化失败,确认连接已断开"); UpdateConnectionStatus(ConnectionStatus.Disconnected, "设备未初始化,连接已断开"); // 启动自动重连 - if (_autoReconnectEnabled) + if (_isAutoReconnectEnabled) { StartAutoReconnect(); } @@ -974,8 +983,8 @@ namespace JoyD.Windows.CS.Toprie { UpdateConnectionStatus(ConnectionStatus.Disconnected, "连接检查异常", ex); _isInitialized = false; - // 启动自动重连 - if (_autoReconnectEnabled) + // 启动自动重连,只有在未暂停检测时才执行 + if (_isAutoReconnectEnabled && !IsDetectionPaused) { StartAutoReconnect(); } @@ -1027,9 +1036,11 @@ namespace JoyD.Windows.CS.Toprie // 先检查对象状态,避免不必要的操作 lock (_lockObject) { - if (_isDisposed || _connectionStatus != ConnectionStatus.Connected) + if (_isDisposed || _connectionStatus != ConnectionStatus.Connected || IsDetectionPaused) { - Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] CheckConnectionWrapper() - 对象已释放或连接状态非Connected,跳过检查"); + string reason = _isDisposed ? "对象已释放" : + (_connectionStatus != ConnectionStatus.Connected ? "连接状态非Connected" : "检测已暂停"); + Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] CheckConnectionWrapper() - {reason},跳过检查"); return; } } @@ -1086,8 +1097,8 @@ namespace JoyD.Windows.CS.Toprie UpdateConnectionStatus(ConnectionStatus.Disconnected, "连接已断开:设备离线"); - // 断开连接后自动启动重连,但在锁外执行 - if (_autoReconnectEnabled) + // 断开连接后自动启动重连,但在锁外执行,只有在未暂停检测时才执行 + if (_isAutoReconnectEnabled && !IsDetectionPaused) { Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] CheckConnectionWrapper() - 连接断开,将启动自动重连"); // 在锁外启动自动重连,避免潜在的死锁 @@ -1114,6 +1125,13 @@ namespace JoyD.Windows.CS.Toprie Log("设计模式下跳过实际的连接有效性检查,模拟连接有效"); return true; } + + // 在暂停检测模式下,跳过连接有效性检查,直接返回连接有效 + if (IsDetectionPaused) + { + Log("暂停检测模式下跳过连接有效性检查,模拟连接有效"); + return true; + } // 注意:此方法被CheckConnectionWrapper调用,已经在线程安全的上下文中 // 不需要额外加锁,但需要确保SDK实例的访问是线程安全的 @@ -3375,7 +3393,7 @@ namespace JoyD.Windows.CS.Toprie // 连接进行中标志(用于防止重连期间再次触发连接) private volatile bool _isConnecting = false; - private void StartAutoReconnect() + public void StartAutoReconnect() { Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StartAutoReconnect() - 开始执行"); @@ -3386,6 +3404,13 @@ namespace JoyD.Windows.CS.Toprie return; } + // 在暂停检测模式下,跳过重连启动 + if (IsDetectionPaused) + { + Log("暂停检测模式下跳过重连启动"); + return; + } + // 检查对象是否已释放 if (_isDisposed) { @@ -3591,6 +3616,13 @@ namespace JoyD.Windows.CS.Toprie return; } + // 在暂停检测模式下,跳过重连操作 + if (IsDetectionPaused) + { + Log("暂停检测模式下跳过实际的重连操作"); + return; + } + Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] ReconnectCallback() - 开始执行"); // 使用Interlocked.Exchange实现原子操作检查,防止重入 From c525b938afbcca9c2a19cc4a7e2e785c46ae07c9 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 14:39:24 +0800 Subject: [PATCH 51/64] =?UTF-8?q?=E4=BF=AE=E6=94=B9InfoImage=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BB=8E?= =?UTF-8?q?=E9=87=8A=E6=94=BE=E8=B5=84=E6=BA=90=E6=94=B9=E4=B8=BA=E7=AE=80?= =?UTF-8?q?=E5=8D=95=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 91 +++++++++++-------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 1868c84..b0fe509 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -81,9 +81,10 @@ namespace JoyD.Windows.CS.Toprie /// /// 更新InfoImage显示 - /// 1. 如果断开,显示重连信息 - /// 2. 否则如果暂停,显示暂停信息 - /// 3. 最后调用更新UI + /// 1. 如果暂停,显示暂停信息 + /// 2. 否则如果Ping不通或断开,显示重连信息 + /// 3. 否则清空InfoImage + /// 4. 最后调用更新UI /// private void UpdateInfo() { @@ -95,17 +96,9 @@ namespace JoyD.Windows.CS.Toprie { lock (_infoImageLock) { - // 释放之前的InfoImage资源 + // 清理InfoImage if (_infoImage != null) { - try - { - _infoImage.Dispose(); - } - catch (Exception ex) - { - Console.WriteLine($"释放InfoImage资源异常: {ex.Message}"); - } _infoImage = null; } @@ -115,9 +108,39 @@ namespace JoyD.Windows.CS.Toprie bool isPaused = _isPaused; // 使用_isPaused标志判断暂停状态 bool isPingFailed = !IsDevicePingable; - // 如果需要显示信息,创建InfoImage - if (isDisconnected || isReconnecting || isPaused || isPingFailed) - { + // 根据用户要求的优先级显示信息:先检查暂停状态,然后再检查Ping状态和连接状态 + if (isPaused) + { + // 暂停状态 - 最高优先级 + _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); + using (Graphics g = Graphics.FromImage(_infoImage)) + { + // 设置半透明背景 + using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black))) + { + g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); + } + + // 绘制暂停文本 + string text = "暂停"; + Color textColor = Color.Red; + + using (Font font = new Font("Arial", 48, FontStyle.Bold)) + using (SolidBrush textBrush = new SolidBrush(textColor)) + { + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + + // 将主文本居中显示 + g.DrawString(text, font, textBrush, + new RectangleF(0, BUFFER_HEIGHT / 3, BUFFER_WIDTH, BUFFER_HEIGHT / 3), + format); + } + } + } + else if (isPingFailed || isDisconnected || isReconnecting) + { + // 非暂停状态下,检查Ping状态和连接状态 _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); using (Graphics g = Graphics.FromImage(_infoImage)) { @@ -131,30 +154,19 @@ namespace JoyD.Windows.CS.Toprie string text = ""; Color textColor = Color.White; - // 根据要求的优先级显示信息:先检查Ping状态和连接状态,最后检查暂停状态 - if (isPingFailed || isDisconnected || isReconnecting) - { - // Ping不通或断开连接状态 - if (isReconnecting) - { - text = "正在重连..."; - textColor = Color.Yellow; - } - else if (isDisconnected) - { - text = "连接断开"; - textColor = Color.Red; - } - else if (isPingFailed) - { - text = "连接断开"; - textColor = Color.Red; - } + if (isReconnecting) + { + text = "正在重连..."; + textColor = Color.Yellow; } - else if (isPaused) - { - // 暂停状态 - text = "暂停"; + else if (isDisconnected) + { + text = "连接断开"; + textColor = Color.Red; + } + else if (isPingFailed) + { + text = "连接断开"; textColor = Color.Red; } @@ -172,9 +184,10 @@ namespace JoyD.Windows.CS.Toprie } } } + // 否则清空InfoImage(已在开头处理) // 设置显示标志 - _isDisplayingInfo = (isDisconnected || isReconnecting || isPaused); + _isDisplayingInfo = (isPaused || isDisconnected || isReconnecting); } // 调用更新UI From ba255790f93184baa5278a7b091390ee69776de2 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 14:42:23 +0800 Subject: [PATCH 52/64] =?UTF-8?q?=E7=A7=BB=E9=99=A4=5FinfoImage=E7=9A=84?= =?UTF-8?q?=E6=B8=85=E7=90=86=E4=BB=A3=E7=A0=81=EF=BC=8C=E7=A1=AE=E8=AE=A4?= =?UTF-8?q?=5FinfoImage=E4=BD=9C=E4=B8=BA=E5=85=A8=E5=B1=80=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E7=94=B1=E6=8E=A7=E4=BB=B6Dispose=E6=97=B6=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E9=87=8A=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index b0fe509..0858d9e 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -95,13 +95,7 @@ namespace JoyD.Windows.CS.Toprie try { lock (_infoImageLock) - { - // 清理InfoImage - if (_infoImage != null) - { - _infoImage = null; - } - + { // 检查连接状态 bool isDisconnected = _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Disconnected; bool isReconnecting = _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Reconnecting; @@ -112,7 +106,6 @@ namespace JoyD.Windows.CS.Toprie if (isPaused) { // 暂停状态 - 最高优先级 - _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); using (Graphics g = Graphics.FromImage(_infoImage)) { // 设置半透明背景 From b3a747aa0699aa541f01b19227bf3a21588efd7d Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 14:46:29 +0800 Subject: [PATCH 53/64] =?UTF-8?q?=E4=BC=98=E5=8C=96UpdateImageOnUI?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=8C=E6=B6=88=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=9A1.=20=E5=B0=86=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=A3=80=E6=9F=A5=E7=A7=BB=E5=88=B0=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E5=BC=80=E5=A7=8B=E5=A4=84=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E6=A3=80=E6=9F=A5=EF=BC=9B2.=20=E5=90=88?= =?UTF-8?q?=E5=B9=B6=5FimageBuffer=E7=9A=84=E9=94=81=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=EF=BC=8C=E5=87=8F=E5=B0=91=E9=94=81=E7=AB=9E=E4=BA=89=EF=BC=9B?= =?UTF-8?q?3.=20=E5=88=9B=E5=BB=BA=E7=BB=9F=E4=B8=80=E7=9A=84DisposeImage?= =?UTF-8?q?=E8=BE=85=E5=8A=A9=E6=96=B9=E6=B3=95=E5=A4=84=E7=90=86=E5=9B=BE?= =?UTF-8?q?=E5=83=8F=E8=B5=84=E6=BA=90=E9=87=8A=E6=94=BE=EF=BC=9B4.=20?= =?UTF-8?q?=E9=A2=84=E5=AE=9A=E4=B9=89displayImage=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E4=BB=A5=E6=8F=90=E9=AB=98=E4=BB=A3=E7=A0=81=E5=8F=AF=E8=AF=BB?= =?UTF-8?q?=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 0858d9e..c008239 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -134,7 +134,6 @@ namespace JoyD.Windows.CS.Toprie else if (isPingFailed || isDisconnected || isReconnecting) { // 非暂停状态下,检查Ping状态和连接状态 - _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); using (Graphics g = Graphics.FromImage(_infoImage)) { // 设置半透明背景 @@ -646,15 +645,20 @@ namespace JoyD.Windows.CS.Toprie return; } + // 一次性控件有效性检查,避免重复检查 + if (this.IsDisposed || imageBox == null || imageBox.IsDisposed) + { + Console.WriteLine("控件已释放,无法更新图像"); + return; + } + Image lastImage = null; Image infoImage = null; Image oldImage = null; + Bitmap displayImage = null; try { - // 移除连接状态检查,确保在任何状态下都能更新UI - // 根据流程要求,需要在断开或Ping不通时也能显示相关信息 - // 检查图像缓冲区是否有效 if (_imageBuffer == null) { @@ -667,13 +671,6 @@ namespace JoyD.Windows.CS.Toprie } } - // 更新图像前先检查控件是否存在/已释放 - if (this.IsDisposed || imageBox == null || imageBox.IsDisposed) - { - Console.WriteLine("控件已释放,无法更新图像"); - return; - } - // 保存旧图像引用,以便在设置新图像后释放 oldImage = imageBox.Image; @@ -695,7 +692,7 @@ namespace JoyD.Windows.CS.Toprie } } - // 在缓冲区上绘制图像 - 按照用户要求的步骤执行 + // 合并锁定,减少锁的数量,提高性能 lock (_imageBuffer) { using (Graphics g = Graphics.FromImage(_imageBuffer)) @@ -731,12 +728,8 @@ namespace JoyD.Windows.CS.Toprie } } } - } - - // 步骤3:创建缓冲区的副本用于显示,避免在显示时锁定缓冲区 - Bitmap displayImage = null; - lock (_imageBuffer) - { + + // 在同一个锁内创建缓冲区的副本,避免重复锁定 displayImage = (Bitmap)_imageBuffer.Clone(); } @@ -753,8 +746,8 @@ namespace JoyD.Windows.CS.Toprie // 特别处理"参数无效"异常 Console.WriteLine($"图像参数无效异常: {ex.Message}"); - // 尝试设置旧图像回来,如果可能的话 - if (oldImage != null && !this.IsDisposed && imageBox != null && !imageBox.IsDisposed) + // 尝试设置旧图像回来,不需要再次检查控件状态(已在方法开始处检查) + if (oldImage != null) { try { @@ -763,7 +756,7 @@ namespace JoyD.Windows.CS.Toprie catch { // 如果设置旧图像也失败,释放它 - try { oldImage.Dispose(); } catch {} + DisposeImage(oldImage); } } } @@ -774,9 +767,24 @@ namespace JoyD.Windows.CS.Toprie finally { // 确保在任何情况下都释放资源 - if (lastImage != null) { try { lastImage.Dispose(); } catch { } } - if (infoImage != null) { try { infoImage.Dispose(); } catch { } } - if (oldImage != null && oldImage != imageBox.Image) { try { oldImage.Dispose(); } catch { } } + DisposeImage(lastImage); + DisposeImage(infoImage); + // 只有当旧图像不再被使用时才释放 + if (oldImage != null && oldImage != imageBox.Image) + { + DisposeImage(oldImage); + } + } + } + + /// + /// 安全释放图像资源的辅助方法 + /// + private void DisposeImage(Image image) + { + if (image != null) + { + try { image.Dispose(); } catch { } } } From 848c0680422f5387fef8c76e307d810a61b6dae2 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 14:48:59 +0800 Subject: [PATCH 54/64] =?UTF-8?q?=E5=B0=86=E5=9B=BE=E5=83=8F=E7=BC=93?= =?UTF-8?q?=E5=86=B2=E5=8C=BA=E7=9A=84=E8=83=8C=E6=99=AF=E8=89=B2=E4=BB=8E?= =?UTF-8?q?=E9=BB=91=E8=89=B2=E6=94=B9=E4=B8=BA=E9=80=8F=E6=98=8E=E8=89=B2?= =?UTF-8?q?=EF=BC=8C=E7=A1=AE=E4=BF=9D=E7=83=AD=E5=9B=BE=E8=83=BD=E5=A4=9F?= =?UTF-8?q?=E6=AD=A3=E5=B8=B8=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index c008239..651bc52 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -697,8 +697,8 @@ namespace JoyD.Windows.CS.Toprie { using (Graphics g = Graphics.FromImage(_imageBuffer)) { - // 清除缓冲区背景为黑色 - g.Clear(Color.Black); + // 清除缓冲区背景为透明色,确保热图能够正常显示 + g.Clear(Color.Transparent); // 步骤1:先将LastImage绘制到全局缓冲 if (lastImage != null) From a6a6563c1b322a441974366d49250342e192f35b Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 14:50:45 +0800 Subject: [PATCH 55/64] =?UTF-8?q?=E5=B0=86=E5=9B=BE=E5=83=8F=E7=BC=93?= =?UTF-8?q?=E5=86=B2=E5=8C=BA=E7=9A=84=E8=83=8C=E6=99=AF=E8=89=B2=E4=BB=8E?= =?UTF-8?q?=E9=80=8F=E6=98=8E=E8=89=B2=E6=94=B9=E5=9B=9E=E9=BB=91=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 651bc52..c008239 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -697,8 +697,8 @@ namespace JoyD.Windows.CS.Toprie { using (Graphics g = Graphics.FromImage(_imageBuffer)) { - // 清除缓冲区背景为透明色,确保热图能够正常显示 - g.Clear(Color.Transparent); + // 清除缓冲区背景为黑色 + g.Clear(Color.Black); // 步骤1:先将LastImage绘制到全局缓冲 if (lastImage != null) From 444c62efe4b2cf4894187c1b1f4b86098a0a795a Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 15:01:57 +0800 Subject: [PATCH 56/64] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=9B=BE=E5=83=8F?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E7=AE=A1=E7=90=86=EF=BC=9A1.=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E6=97=B6=E5=88=9B=E5=BB=BA512x384=E9=80=8F?= =?UTF-8?q?=E6=98=8Ebitmap=202.=E4=B8=AD=E9=80=94=E4=B8=8D=E8=BF=9B?= =?UTF-8?q?=E8=A1=8CDispose=E5=92=8C=E8=AE=BE=E7=BD=AE=E4=B8=BAnull=203.?= =?UTF-8?q?=E4=BB=85=E5=9C=A8=E6=8E=A7=E4=BB=B6Dispose=E6=97=B6=E9=87=8A?= =?UTF-8?q?=E6=94=BE=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 69 +++++++++++++++---- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index c008239..43ec5fe 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -353,27 +353,61 @@ namespace JoyD.Windows.CS.Toprie } /// - /// 初始化图像缓冲区 + /// 初始化图像缓冲区和相关图像资源 /// private void InitializeImageBuffer() { try { - // 创建512*384大小的bitmap作为图像缓冲区 + // 创建512*384大小的透明bitmap作为图像缓冲区 _imageBuffer = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); Console.WriteLine($"图像缓冲区已初始化: {BUFFER_WIDTH}x{BUFFER_HEIGHT}"); - // 初始化缓冲区为黑色背景 + // 初始化缓冲区为透明背景 using (Graphics g = Graphics.FromImage(_imageBuffer)) { - g.Clear(Color.Black); + g.Clear(Color.Transparent); + } + + // 初始化InfoImage为透明bitmap + lock (_infoImageLock) + { + _infoImage = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); + using (Graphics g = Graphics.FromImage(_infoImage)) + { + g.Clear(Color.Transparent); + } + Console.WriteLine("InfoImage已初始化为透明bitmap"); + } + + // 初始化图像框的bitmap为透明 + if (imageBox != null && !imageBox.IsDisposed) + { + imageBox.Image = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); + using (Graphics g = Graphics.FromImage(imageBox.Image)) + { + g.Clear(Color.Transparent); + } + Console.WriteLine("图像框bitmap已初始化为透明"); } } catch (Exception ex) { - Console.WriteLine($"初始化图像缓冲区失败: {ex.Message}"); - // 如果初始化失败,确保_imageBuffer为null - _imageBuffer = null; + Console.WriteLine($"初始化图像资源失败: {ex.Message}"); + // 发生异常时释放已创建的资源 + if (_imageBuffer != null) + { + _imageBuffer.Dispose(); + _imageBuffer = null; + } + lock (_infoImageLock) + { + if (_infoImage != null) + { + _infoImage.Dispose(); + _infoImage = null; + } + } } } @@ -581,15 +615,22 @@ namespace JoyD.Windows.CS.Toprie } // 按照用户要求:收到图像数据后,将图像保存到LastImage中 + // 不释放旧的LastImage,仅在控件Dispose时释放 lock (_lastImageLock) { - // 释放旧的LastImage资源 - if (_lastImage != null) + // 如果是第一次设置LastImage,直接赋值 + if (_lastImage == null) { - try { _lastImage.Dispose(); } catch {} + _lastImage = newImage; + } + else + { + // 后续更新时,使用临时变量保存新图像,然后替换引用 + Image temp = newImage; + newImage = _lastImage; + _lastImage = temp; + // 注意:这里不Dispose旧图像,只在控件Dispose时统一释放 } - // 设置新的LastImage - _lastImage = newImage; } // 按照用户要求:调用更新到UI @@ -697,8 +738,8 @@ namespace JoyD.Windows.CS.Toprie { using (Graphics g = Graphics.FromImage(_imageBuffer)) { - // 清除缓冲区背景为黑色 - g.Clear(Color.Black); + // 清除缓冲区背景为透明色 + g.Clear(Color.Transparent); // 步骤1:先将LastImage绘制到全局缓冲 if (lastImage != null) From 58ac23b57bd5f0582279c7d02b06c832b2d07d12 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 15:21:16 +0800 Subject: [PATCH 57/64] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 72 +++++++------------ .../CS/Framework4.0/Toprie/Toprie/README.md | 18 +++++ 2 files changed, 42 insertions(+), 48 deletions(-) create mode 100644 Windows/CS/Framework4.0/Toprie/Toprie/README.md diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 43ec5fe..fae974a 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -101,19 +101,19 @@ namespace JoyD.Windows.CS.Toprie bool isReconnecting = _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Reconnecting; bool isPaused = _isPaused; // 使用_isPaused标志判断暂停状态 bool isPingFailed = !IsDevicePingable; - + // 根据用户要求的优先级显示信息:先检查暂停状态,然后再检查Ping状态和连接状态 - if (isPaused) - { - // 暂停状态 - 最高优先级 - using (Graphics g = Graphics.FromImage(_infoImage)) + + using (Graphics g = Graphics.FromImage(_infoImage)) + { + // 设置半透明背景 + using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Transparent))) { - // 设置半透明背景 - using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black))) - { - g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); - } - + g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); + } + if (isPaused) + { + // 暂停状态 - 最高优先级 // 绘制暂停文本 string text = "暂停"; Color textColor = Color.Red; @@ -130,17 +130,9 @@ namespace JoyD.Windows.CS.Toprie format); } } - } - else if (isPingFailed || isDisconnected || isReconnecting) - { - // 非暂停状态下,检查Ping状态和连接状态 - using (Graphics g = Graphics.FromImage(_infoImage)) - { - // 设置半透明背景 - using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Black))) - { - g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); - } + else if (isPingFailed || isDisconnected || isReconnecting) + { + // 非暂停状态下,检查Ping状态和连接状态 // 确定显示的文本和颜色 string text = ""; @@ -589,11 +581,8 @@ namespace JoyD.Windows.CS.Toprie if (ms.CanRead && ms.Length > 0) { // 从流中创建图像 - using (Image tempImage = System.Drawing.Image.FromStream(ms)) - { - // 创建一个全新的位图而仅仅是克隆,确保数据完整性 - Image newImage = new Bitmap(tempImage); - + using (Image newImage = System.Drawing.Image.FromStream(ms)) + { // 立即验证新创建的图像是否有效 try { @@ -603,36 +592,23 @@ namespace JoyD.Windows.CS.Toprie if (width <= 0 || height <= 0) { Console.WriteLine("创建的图像尺寸无效"); - newImage.Dispose(); return; } + if (_lastImage == null) _lastImage = new Bitmap(newImage); + else + { + using(Graphics g= Graphics.FromImage(_lastImage)) + { + g.DrawImage(newImage,Point.Empty); + } + } } catch (Exception) { Console.WriteLine("创建的图像无效"); - newImage.Dispose(); return; } - // 按照用户要求:收到图像数据后,将图像保存到LastImage中 - // 不释放旧的LastImage,仅在控件Dispose时释放 - lock (_lastImageLock) - { - // 如果是第一次设置LastImage,直接赋值 - if (_lastImage == null) - { - _lastImage = newImage; - } - else - { - // 后续更新时,使用临时变量保存新图像,然后替换引用 - Image temp = newImage; - newImage = _lastImage; - _lastImage = temp; - // 注意:这里不Dispose旧图像,只在控件Dispose时统一释放 - } - } - // 按照用户要求:调用更新到UI // 只有当图像更新未暂停时才更新UI if (!_isPaused) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/README.md b/Windows/CS/Framework4.0/Toprie/Toprie/README.md new file mode 100644 index 0000000..44edfae --- /dev/null +++ b/Windows/CS/Framework4.0/Toprie/Toprie/README.md @@ -0,0 +1,18 @@ +# JoyD + +### InfoImage, ImageBuffer, 图像框的bitmap, LastImage +1. 初始化时,都创建成512x384的透明bitmap +2. 中途不进行Dispose和设置为null,只在上面进行绘制 +3. 仅当控件被Dispose时,才进行Dispose和设置为null +### 修改流程: + 1. 暂停或恢复时,设置暂停状态,调用更新Info + 2. 断开或连接时,设置连接状态,调用更新Info + 3. Ping通状态变化时,修改Ping状态,调用更新Info + 4. 图像更新时, 保存LastImage, 调用更新到UI + ### 更新Info: + 1. 如果暂停,显示暂停信息,否则如果Ping不通或断开,显示重连信息,否则清空InfoImage + 2. 最后调用更新UI + ### 更新UI: + 1. 先将LastImage绘制到全局缓冲 + 2. 再将InfoImage绘制到缓冲 + 3. 最后一次性绘制到图像框的bitmap \ No newline at end of file From a6bb9b88128bdb4dc0c64eb1782ff18fa7d10171 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 15:25:59 +0800 Subject: [PATCH 58/64] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index fae974a..e3481fa 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -112,32 +112,32 @@ namespace JoyD.Windows.CS.Toprie g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); } if (isPaused) - { + { // 暂停状态 - 最高优先级 // 绘制暂停文本 string text = "暂停"; Color textColor = Color.Red; - + using (Font font = new Font("Arial", 48, FontStyle.Bold)) using (SolidBrush textBrush = new SolidBrush(textColor)) { StringFormat format = new StringFormat(); format.Alignment = StringAlignment.Center; - + // 将主文本居中显示 - g.DrawString(text, font, textBrush, - new RectangleF(0, BUFFER_HEIGHT / 3, BUFFER_WIDTH, BUFFER_HEIGHT / 3), + g.DrawString(text, font, textBrush, + new RectangleF(0, BUFFER_HEIGHT / 3, BUFFER_WIDTH, BUFFER_HEIGHT / 3), format); } } else if (isPingFailed || isDisconnected || isReconnecting) - { + { // 非暂停状态下,检查Ping状态和连接状态 - + // 确定显示的文本和颜色 string text = ""; Color textColor = Color.White; - + if (isReconnecting) { text = "正在重连..."; @@ -153,20 +153,21 @@ namespace JoyD.Windows.CS.Toprie text = "连接断开"; textColor = Color.Red; } - + // 绘制文本 using (Font font = new Font("Arial", 48, FontStyle.Bold)) using (SolidBrush textBrush = new SolidBrush(textColor)) { StringFormat format = new StringFormat(); format.Alignment = StringAlignment.Center; - + // 将主文本居中显示 - g.DrawString(text, font, textBrush, - new RectangleF(0, BUFFER_HEIGHT / 3, BUFFER_WIDTH, BUFFER_HEIGHT / 3), + g.DrawString(text, font, textBrush, + new RectangleF(0, BUFFER_HEIGHT / 3, BUFFER_WIDTH, BUFFER_HEIGHT / 3), format); } } + else g.Clear(Color.Transparent); } // 否则清空InfoImage(已在开头处理) From acc250900566b3c008d2f3d97ea22fa5044e5510 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 15:40:45 +0800 Subject: [PATCH 59/64] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index e3481fa..a9e22ae 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -107,10 +107,7 @@ namespace JoyD.Windows.CS.Toprie using (Graphics g = Graphics.FromImage(_infoImage)) { // 设置半透明背景 - using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, Color.Transparent))) - { - g.FillRectangle(brush, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT); - } + g.Clear(Color.FromArgb(128, Color.Transparent)); if (isPaused) { // 暂停状态 - 最高优先级 @@ -150,7 +147,7 @@ namespace JoyD.Windows.CS.Toprie } else if (isPingFailed) { - text = "连接断开"; + text = "网络断开"; textColor = Color.Red; } From 63ebe4faa19d7f84653c49bf94abe09d05ca49a3 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 15:49:10 +0800 Subject: [PATCH 60/64] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=92=8CSDK=E5=AE=9E=E4=BE=8B=E7=AE=A1?= =?UTF-8?q?=E7=90=86=EF=BC=9A1.=20=E8=8F=9C=E5=8D=95=E4=BB=85=E5=9C=A8?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E6=88=90=E5=8A=9F=E6=97=B6=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=202.=20=E5=A2=9E=E5=BC=BA=E5=A4=9A=E7=BA=BF=E7=A8=8B=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E4=B8=8B=E7=9A=84SDK=E5=AE=9E=E4=BE=8B=E8=AE=BF?= =?UTF-8?q?=E9=97=AE=E5=AE=89=E5=85=A8=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Camera.cs | 17 ++- .../Toprie/Toprie/DeviceManager.cs | 104 ++++++++++++++---- 2 files changed, 93 insertions(+), 28 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index a9e22ae..750db86 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -1169,9 +1169,12 @@ namespace JoyD.Windows.CS.Toprie // 检查是否处于暂停状态 bool isPaused = pauseDetectionToolStripMenuItem.Text == "恢复检测"; - // 在暂停状态下,隐藏图像模式根菜单和色彩模式菜单 + // 检查设备是否已连接 + bool isConnected = _deviceManager != null && _deviceManager.ConnectionStatus == ConnectionStatus.Connected; + + // 在暂停状态或未连接状态下,隐藏图像模式根菜单和色彩模式菜单 // 注意:根菜单隐藏后,其所有子菜单会自动隐藏,不需要单独设置 - if (isPaused) + if (isPaused || !isConnected) { // 隐藏图像模式根菜单 if (imageModeToolStripMenuItem != null) @@ -1185,20 +1188,16 @@ namespace JoyD.Windows.CS.Toprie } else { - // 在非暂停状态下,显示图像模式根菜单 + // 在非暂停状态且已连接状态下,显示图像模式根菜单 // 注意:根菜单显示后,其所有子菜单会自动显示,不需要单独设置 if (imageModeToolStripMenuItem != null) imageModeToolStripMenuItem.Visible = true; - // 在非暂停状态下,显示分隔符 + // 在非暂停状态且已连接状态下,显示分隔符 toolStripSeparator1.Visible = true; // 根据当前图像模式控制色彩模式菜单的可见性 - if (_deviceManager != null) - { - colorModeToolStripMenuItem.Visible = _deviceManager.CurrentImageMode == ImageMode.Infrared; - } - + colorModeToolStripMenuItem.Visible = _deviceManager.CurrentImageMode == ImageMode.Infrared; // 清除视频模式菜单项的选中状态 thermalModeToolStripMenuItem.Checked = false; visibleModeToolStripMenuItem.Checked = false; diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index 9eda918..bb9b0ef 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -2459,29 +2459,52 @@ namespace JoyD.Windows.CS.Toprie { try { - // 确保设备已连接且SDK实例有效 - if (_connectionStatus == ConnectionStatus.Connected && _a8Sdk != null) + // 使用SDK操作锁保护对_a8Sdk的访问 + lock (_sdkOperationLock) { - // 获取当前设备的色彩模式值 - int currentValue = _a8Sdk.GetColorPlate(); - Log($"从设备读取的色彩模式值: {currentValue}"); - - // 尝试将读取到的值转换为PaletteType枚举并更新内部状态 - if (Enum.IsDefined(typeof(PaletteType), currentValue)) + // 确保设备已连接且SDK实例有效 + if (_connectionStatus == ConnectionStatus.Connected && _a8Sdk != null) { - PaletteType actualPalette = (PaletteType)currentValue; - _currentPaletteType = actualPalette; - Log($"已更新内部状态为设备实际值: {actualPalette}"); + try + { + // 获取当前设备的色彩模式值 + int currentValue = _a8Sdk.GetColorPlate(); + Log($"从设备读取的色彩模式值: {currentValue}"); + + // 尝试将读取到的值转换为PaletteType枚举并更新内部状态 + if (Enum.IsDefined(typeof(PaletteType), currentValue)) + { + PaletteType actualPalette = (PaletteType)currentValue; + _currentPaletteType = actualPalette; + Log($"已更新内部状态为设备实际值: {actualPalette}"); + } + else + { + Log($"警告:设备返回的色彩模式值 {currentValue} 不在枚举定义范围内,使用默认值"); + } + } + catch (Exception ex) + { + Log($"从设备读取色彩模式时出错: {ex.Message}"); + // 尝试重新创建SDK实例 + Log("尝试重新创建SDK实例..."); + try + { + _a8Sdk = new A8SDK(_deviceIp); + Log("SDK实例已重新创建"); + } + catch (Exception recreateEx) + { + Log($"重新创建SDK实例失败: {recreateEx.Message}"); + } + throw; + } } else { - Log($"警告:设备返回的色彩模式值 {currentValue} 不在枚举定义范围内,使用默认值"); + Log($"同步色彩模式失败:设备未连接或SDK未初始化"); } } - else - { - Log($"同步色彩模式失败:设备未连接或SDK未初始化"); - } } catch (Exception ex) { @@ -2515,11 +2538,27 @@ namespace JoyD.Windows.CS.Toprie // 重试间隔(毫秒) const int retryDelayMs = 100; + // 确保SDK实例存在,如果不存在则尝试创建 + if (_a8Sdk == null) + { + Log("SDK实例为空,尝试创建新实例..."); + try + { + _a8Sdk = new A8SDK(_deviceIp); + Log("SDK实例创建成功"); + } + catch (Exception ex) + { + Log($"创建SDK实例失败: {ex.Message}"); + return false; + } + } + // 先获取原始值,只读取一次,避免嵌套调用 int originalValue = -1; try { - if (_a8Sdk != null && _connectionStatus == ConnectionStatus.Connected) + if (_connectionStatus == ConnectionStatus.Connected) { originalValue = _a8Sdk.Color_plate; Log($"成功读取当前色彩模式值: {originalValue}"); @@ -2528,6 +2567,17 @@ namespace JoyD.Windows.CS.Toprie catch (Exception ex) { Log($"获取当前色彩模式值时出错: {ex.Message}"); + // 尝试重新创建SDK实例 + Log("尝试重新创建SDK实例..."); + try + { + _a8Sdk = new A8SDK(_deviceIp); + Log("SDK实例已重新创建"); + } + catch (Exception recreateEx) + { + Log($"重新创建SDK实例失败: {recreateEx.Message}"); + } // 即使获取失败,仍尝试设置新值 } @@ -2545,8 +2595,24 @@ namespace JoyD.Windows.CS.Toprie { try { - // 检查对象状态和连接状态 - if (_a8Sdk == null || _connectionStatus != ConnectionStatus.Connected) + // 再次确保SDK实例存在 + if (_a8Sdk == null) + { + Log("SDK实例为空,尝试重新创建..."); + try + { + _a8Sdk = new A8SDK(_deviceIp); + Log("SDK实例重新创建成功"); + } + catch (Exception ex) + { + Log($"重新创建SDK实例失败: {ex.Message}"); + continue; // 继续下一次尝试 + } + } + + // 检查连接状态 + if (_connectionStatus != ConnectionStatus.Connected) { Log($"色彩模式设置失败: {(attempt > 0 ? "重试中" : "")}SDK实例为空或设备未连接"); Thread.Sleep(retryDelayMs); From 3c14188938e179189f1e14763aa5863791b8498b Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 15:51:42 +0800 Subject: [PATCH 61/64] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E8=AD=A6=E5=91=8A=EF=BC=9A1.=20=E7=AE=80=E5=8C=96=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E5=88=9D=E5=A7=8B=E5=8C=96=202.=20=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E5=8F=AA=E8=AF=BB=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 6 ++---- Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs | 2 +- .../Framework4.0/Toprie/Toprie/UdpCommunicationManager.cs | 3 +-- Windows/CS/Framework4.0/Toprie/Toprie/V8.cs | 7 ++++--- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 750db86..7463317 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -118,8 +118,7 @@ namespace JoyD.Windows.CS.Toprie using (Font font = new Font("Arial", 48, FontStyle.Bold)) using (SolidBrush textBrush = new SolidBrush(textColor)) { - StringFormat format = new StringFormat(); - format.Alignment = StringAlignment.Center; + StringFormat format = new StringFormat() { Alignment = StringAlignment.Center }; // 将主文本居中显示 g.DrawString(text, font, textBrush, @@ -155,8 +154,7 @@ namespace JoyD.Windows.CS.Toprie using (Font font = new Font("Arial", 48, FontStyle.Bold)) using (SolidBrush textBrush = new SolidBrush(textColor)) { - StringFormat format = new StringFormat(); - format.Alignment = StringAlignment.Center; + StringFormat format = new StringFormat() { Alignment = StringAlignment.Center }; // 将主文本居中显示 g.DrawString(text, font, textBrush, diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index bb9b0ef..14fb337 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -182,7 +182,7 @@ namespace JoyD.Windows.CS.Toprie // 是否已释放 private bool _isDisposed = false; // 图像模式 - private ImageMode _currentImageMode = ImageMode.Infrared; + private readonly ImageMode _currentImageMode = ImageMode.Infrared; // 当前色彩模式 private PaletteType _currentPaletteType = PaletteType.WhiteHot; // 当前视频模式 diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/UdpCommunicationManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/UdpCommunicationManager.cs index 6f5bf00..46b4d53 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/UdpCommunicationManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/UdpCommunicationManager.cs @@ -69,8 +69,7 @@ namespace JoyD.Windows.CS.Toprie // 启动工作线程 _isRunning = true; - _workerThread = new Thread(ProcessRequests); - _workerThread.IsBackground = true; + _workerThread = new Thread(ProcessRequests) { IsBackground = true }; _workerThread.Start(); Console.WriteLine("UDP通信管理器已初始化"); diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs index 294c5e1..970386b 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs @@ -1129,9 +1129,10 @@ namespace JoyD.Windows.CS.Toprie if (SendCommand(command, out string response)) { // 创建默认的ImagePos对象 - SharedStructures.ImagePos data = new SharedStructures.ImagePos(); - data.area = new SharedStructures.AreaPos[6]; - data.spot = new SharedStructures.SpotPos[6]; + SharedStructures.ImagePos data = new SharedStructures.ImagePos() { + area = new SharedStructures.AreaPos[6], + spot = new SharedStructures.SpotPos[6] + }; // 这里应该解析完整的响应数据 // 简化实现,返回默认值 From b2a5295b49c725cc9a1890aa44d9d27d82c80f24 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 15:52:52 +0800 Subject: [PATCH 62/64] =?UTF-8?q?=E8=B0=83=E6=95=B4DeviceManager.cs?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=AD=97=E6=AE=B5=E5=8F=AA=E8=AF=BB=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=EF=BC=9A1.=20=E5=B0=86=5FisDisposed=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E4=B8=BA=E5=8F=AA=E8=AF=BB=202.=20=E7=A7=BB=E9=99=A4=5Fcurrent?= =?UTF-8?q?ImageMode=E7=9A=84=E5=8F=AA=E8=AF=BB=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index 14fb337..830af27 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -180,9 +180,9 @@ namespace JoyD.Windows.CS.Toprie // 是否已初始化 private bool _isInitialized = false; // 是否已释放 - private bool _isDisposed = false; + private readonly bool _isDisposed = false; // 图像模式 - private readonly ImageMode _currentImageMode = ImageMode.Infrared; + private ImageMode _currentImageMode = ImageMode.Infrared; // 当前色彩模式 private PaletteType _currentPaletteType = PaletteType.WhiteHot; // 当前视频模式 From a91b271385b18193173c43c84d7b0a6d873735aa Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 16:00:26 +0800 Subject: [PATCH 63/64] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 7463317..aa822b0 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -351,10 +351,10 @@ namespace JoyD.Windows.CS.Toprie _imageBuffer = new Bitmap(BUFFER_WIDTH, BUFFER_HEIGHT); Console.WriteLine($"图像缓冲区已初始化: {BUFFER_WIDTH}x{BUFFER_HEIGHT}"); - // 初始化缓冲区为透明背景 + // 初始化缓冲区为黑色背景 using (Graphics g = Graphics.FromImage(_imageBuffer)) { - g.Clear(Color.Transparent); + g.Clear(Color.Black); } // 初始化InfoImage为透明bitmap @@ -710,8 +710,8 @@ namespace JoyD.Windows.CS.Toprie { using (Graphics g = Graphics.FromImage(_imageBuffer)) { - // 清除缓冲区背景为透明色 - g.Clear(Color.Transparent); + // 清除缓冲区背景为黑色 + g.Clear(Color.Black); // 步骤1:先将LastImage绘制到全局缓冲 if (lastImage != null) @@ -1195,7 +1195,7 @@ namespace JoyD.Windows.CS.Toprie toolStripSeparator1.Visible = true; // 根据当前图像模式控制色彩模式菜单的可见性 - colorModeToolStripMenuItem.Visible = _deviceManager.CurrentImageMode == ImageMode.Infrared; + colorModeToolStripMenuItem.Visible = true; // 清除视频模式菜单项的选中状态 thermalModeToolStripMenuItem.Checked = false; visibleModeToolStripMenuItem.Checked = false; From 4ab2ddf1f32a38b0b4a91acf6869d379923fd3f1 Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 30 Oct 2025 16:21:26 +0800 Subject: [PATCH 64/64] =?UTF-8?q?=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/todolist.md | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Windows/CS/Framework4.0/Toprie/Toprie/todolist.md diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/todolist.md b/Windows/CS/Framework4.0/Toprie/Toprie/todolist.md new file mode 100644 index 0000000..fef0a0e --- /dev/null +++ b/Windows/CS/Framework4.0/Toprie/Toprie/todolist.md @@ -0,0 +1,54 @@ +# 托普瑞热像仪应用开发任务列表 + +## 1. SDK集成准备 + +- [x] 1.1 复制托普瑞SDK文件到项目目录 +- [x] 1.2 在Visual Studio项目中添加SDK引用 +- [x] 1.3 阅读SDK文档,了解API接口 + +## 2. 设备连接功能 + +- [x] 2.1 实现设备连接模块 +- [x] 2.2 完善连接状态管理 + +## 3. 温度数据处理 + +### 3.1 设备连接建立与管理 +- [ ] 3.1.1 实现设备连接建立流程 + - 使用SDK的`sdk_initialize()`初始化套接字库 + - 利用`sdk_search_device()`搜索设备IP地址 + - 验证设备IP地址是否为默认地址(192.168.100.2)或自定义地址 + - 建立与热像仪的TCP连接,使用8081端口获取原始温度数据 +- [ ] 3.1.2 连接状态维护机制 + - 利用现有的`_heartbeatTimer`实现SDK心跳检测(`sdk_heartbeat`) + - 扩展`UpdateConnectionStatus()`方法,支持温度数据连接状态管理 + - 实现基于`_connectionCheckTimer`的定时连接状态检测 + - 利用现有的自动重连机制,当温度数据连接断开时自动重连 +- [ ] 3.1.3 连接条件判断 + - 调用`IsNetworkAvailable()`验证网络连接状态 + - 检查设备型号兼容性,支持IRAY-A8系列设备 + - 验证设备版本信息,确保SDK兼容性 + - 在获取温度数据前检查设备是否处于正常工作状态 + +### 3.2 原始温度数据获取 +- [ ] 3.2.1 温度数据获取方法实现 + - 在`DeviceManager.cs`中添加`GetRawTemperatureData()`方法 + - 创建TCP客户端连接到设备的8081端口 + - 实现数据接收线程,使用类似现有的`_imageReceiveThread`模式 + - 实现24字节头部结构体解析,提取mark("+TEMP")、payload_length和timestamp +- [ ] 3.2.2 温度数据解析与处理 + - 根据设备分辨率计算温度数据总长度(宽*高*2字节) + - 实现温度数据解码算法:摄氏温度 = (H*256 + L)/10,其中L是低8位,H是高8位 + - 调用`sdk_get_comp_temp()`获取设备温补值并进行叠加修正 + - 创建温度数据模型类,存储解析后的温度矩阵 +- [ ] 3.2.3 数据获取条件控制与异常处理 + - 添加连接状态验证,确保`_connectionStatus`为`Connected` + - 实现数据接收超时处理,基于`_lastDataReceivedTime`和`DataReceivedTimeout` + - 添加数据校验机制,确保接收到的温度数据格式正确 + - 实现断线自动重连,利用现有的`_reconnectTimer`机制 + - 添加异常捕获和日志记录,使用现有的`Log()`方法 +- [ ] 3.2.4 温度数据接口设计 + - 添加温度数据接收事件`TemperatureDataReceived` + - 实现线程安全的数据访问方法 + - 添加温度数据缓存机制,保留最近几帧数据 + - 提供获取特定区域温度数据的辅助方法 \ No newline at end of file