From e7f9985c45dad9eb552c2e16b4b4e14974c848a0 Mon Sep 17 00:00:00 2001 From: zqm Date: Fri, 9 Jan 2026 14:31:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E6=B8=A9=E5=8C=BA=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E6=97=B6=E5=9D=90=E6=A0=87=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/Toprie/Toprie/Setting.cs | 293 +++++++++++++++--- 1 file changed, 245 insertions(+), 48 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs index 7a26739..33bd042 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs @@ -79,7 +79,40 @@ namespace JoyD.Windows.CS public DetectionZone CurrentDetectionZone { get { return _detectionZone; } - set { _detectionZone = value; } + set + { + // 如果是首次设置检测区,先同步温度区列表 + bool isFirstTime = (_detectionZone == null || + (_detectionZone.X == 0 && _detectionZone.Y == 0 && + _detectionZone.Width == 0 && _detectionZone.Height == 0)); + + // 设置检测区 + _detectionZone = value; + + if (isFirstTime) + { + // 首次设置检测区,从_drawnRectangles同步到原始测温区列表和绝对测温区列表 + SyncTemperatureZonesFromDrawnRectangles(); + } + else + { + // 检测区发生变化,更新绝对测温区 + UpdateAbsoluteTemperatureZones(); + } + + // 更新绝对温差图数据 + UpdateAbsoluteTempDiffData(); + + // 正确释放叠加层资源后设为 null + if (_rectangleOverlayImage != null) + { + _rectangleOverlayImage.Dispose(); + _rectangleOverlayImage = null; + } + + // 重新创建叠加层图像 + CreateRectangleOverlayImage(); + } } // 检测区修改相关变量 @@ -91,9 +124,6 @@ namespace JoyD.Windows.CS private Point _detectionZoneStartPoint; // 检测区调整开始点 private Rectangle _originalDetectionZoneRect; // 检测区调整开始时的原始矩形 - // 定时器字段 - private readonly Timer _timer; - // 绘制模式标志 private bool _isDrawingMode = false; @@ -105,6 +135,14 @@ namespace JoyD.Windows.CS private Rectangle _currentRectangle = Rectangle.Empty; private bool _isDrawing = false; private List _drawnRectangles = new List(); + // 原始测温区列表(相对于检测区的位置) + private List _originalTemperatureZones = new List(); + // 绝对测温区列表(相对于整个图像的位置,用于绘制和交互) + private List _absoluteTemperatureZones = new List(); + // 原始温差图数据(相对于检测区的位置) + private Dictionary _originalTempDiffData = new Dictionary(); + // 绝对温差图数据(相对于整个图像的位置,用于绘制和交互) + private Dictionary _absoluteTempDiffData = new Dictionary(); private Color _selectedColor = Color.Red; private int _regionCounter = 0; // 叠加层图像 - 用于存储已完成绘制的矩形 @@ -145,10 +183,6 @@ namespace JoyD.Windows.CS // 设置按钮图标 SetButtonIcon(); - // 初始化定时器 - _timer = new Timer { Interval = 1000 }; - _timer.Tick += Timer_Tick; - // 添加窗体大小变化事件处理 this.Resize += new EventHandler(Setting_Resize); @@ -984,6 +1018,19 @@ namespace JoyD.Windows.CS _detectionZone.Height = _tempDetectionZone.Height; _detectionZone.Color = _tempDetectionZone.Color; // 保存颜色 + // 检测区发生变化,更新绝对测温区 + UpdateAbsoluteTemperatureZones(); + + // 更新绝对温差图数据 + UpdateAbsoluteTempDiffData(); + + // 检测区发生变化,正确释放叠加层资源后设为 null + if (_rectangleOverlayImage != null) + { + _rectangleOverlayImage.Dispose(); + _rectangleOverlayImage = null; + } + // 恢复叠加层绘制,显示测温区和温差图 CreateRectangleOverlayImage(); @@ -2425,7 +2472,7 @@ namespace JoyD.Windows.CS // 检查鼠标是否在某个区域内,选择索引号最大的区域 int newHoveredRegionIndex = -1; int maxIndex = -1; - foreach (RegionInfo region in _drawnRectangles) + foreach (RegionInfo region in _absoluteTemperatureZones) { if (region.ImageRectangle.Contains(imagePoint) && region.Index > maxIndex) { @@ -2478,7 +2525,7 @@ namespace JoyD.Windows.CS } // 由于创建了新图像,需要重新绘制所有矩形 - foreach (RegionInfo region in _drawnRectangles) + foreach (RegionInfo region in _absoluteTemperatureZones) { DrawRegionToOverlay(region); } @@ -2492,7 +2539,7 @@ namespace JoyD.Windows.CS } // 重绘所有矩形 - foreach (RegionInfo region in _drawnRectangles) + foreach (RegionInfo region in _absoluteTemperatureZones) { DrawRegionToOverlay(region); } @@ -2559,6 +2606,158 @@ namespace JoyD.Windows.CS } } + /// + /// 根据原始测温区和当前检测区,更新绝对测温区列表 + /// + private void UpdateAbsoluteTemperatureZones() + { + // 清空绝对测温区列表 + _absoluteTemperatureZones.Clear(); + + // 遍历原始测温区,计算绝对位置并添加到绝对测温区列表 + foreach (RegionInfo originalZone in _originalTemperatureZones) + { + // 计算绝对位置 + Rectangle absoluteRect = new Rectangle( + _detectionZone.X + originalZone.ImageRectangle.X, + _detectionZone.Y + originalZone.ImageRectangle.Y, + originalZone.ImageRectangle.Width, + originalZone.ImageRectangle.Height + ); + + // 创建绝对测温区 + RegionInfo absoluteZone = new RegionInfo + { + Index = originalZone.Index, + Color = originalZone.Color, + ImageRectangle = absoluteRect, + ControlRectangle = ImageRectangleToControlRectangle(absoluteRect) + }; + + // 添加到绝对测温区列表 + _absoluteTemperatureZones.Add(absoluteZone); + } + } + + /// + /// 根据原始温差图数据和当前检测区,更新绝对温差图数据 + /// + private void UpdateAbsoluteTempDiffData() + { + // 清空绝对温差图数据 + _absoluteTempDiffData.Clear(); + + // 遍历原始温差图数据,计算绝对位置并添加到绝对温差图数据 + foreach (KeyValuePair originalPoint in _originalTempDiffData) + { + // 计算绝对位置 + Point absolutePoint = new Point( + _detectionZone.X + originalPoint.Key.X, + _detectionZone.Y + originalPoint.Key.Y + ); + + // 添加到绝对温差图数据 + _absoluteTempDiffData[absolutePoint] = originalPoint.Value; + } + } + + /// + /// 从绝对测温区更新原始测温区列表 + /// + private void UpdateOriginalTemperatureZones() + { + // 清空原始测温区列表 + _originalTemperatureZones.Clear(); + + // 遍历绝对测温区,计算相对位置并添加到原始测温区列表 + foreach (RegionInfo absoluteZone in _absoluteTemperatureZones) + { + // 计算相对位置(相对于检测区) + Rectangle relativeRect = new Rectangle( + absoluteZone.ImageRectangle.X - _detectionZone.X, + absoluteZone.ImageRectangle.Y - _detectionZone.Y, + absoluteZone.ImageRectangle.Width, + absoluteZone.ImageRectangle.Height + ); + + // 创建原始测温区 + RegionInfo originalZone = new RegionInfo + { + Index = absoluteZone.Index, + Color = absoluteZone.Color, + ImageRectangle = relativeRect, + ControlRectangle = ImageRectangleToControlRectangle(relativeRect) + }; + + // 添加到原始测温区列表 + _originalTemperatureZones.Add(originalZone); + } + } + + /// + /// 从_drawnRectangles同步到原始测温区列表和绝对测温区列表 + /// 用于初始化和加载测温区时 + /// + private void SyncTemperatureZonesFromDrawnRectangles() + { + // 清空原始测温区列表和绝对测温区列表 + _originalTemperatureZones.Clear(); + _absoluteTemperatureZones.Clear(); + + // 遍历_drawnRectangles,同步到原始测温区列表 + foreach (RegionInfo region in _drawnRectangles) + { + // 计算相对位置(相对于检测区) + Rectangle relativeRect = new Rectangle( + region.ImageRectangle.X - _detectionZone.X, + region.ImageRectangle.Y - _detectionZone.Y, + region.ImageRectangle.Width, + region.ImageRectangle.Height + ); + + // 创建原始测温区 + RegionInfo originalZone = new RegionInfo + { + Index = region.Index, + Color = region.Color, + ImageRectangle = relativeRect, + ControlRectangle = ImageRectangleToControlRectangle(relativeRect) + }; + + // 添加到原始测温区列表 + _originalTemperatureZones.Add(originalZone); + } + + // 更新绝对测温区列表 + UpdateAbsoluteTemperatureZones(); + } + + /// + /// 从绝对测温区列表同步到_drawnRectangles + /// 用于绝对测温区发生变化时 + /// + private void SyncDrawnRectanglesFromAbsoluteTemperatureZones() + { + // 清空_drawnRectangles + _drawnRectangles.Clear(); + + // 遍历绝对测温区列表,同步到_drawnRectangles + foreach (RegionInfo region in _absoluteTemperatureZones) + { + // 创建新的RegionInfo对象,确保数据独立 + RegionInfo drawnZone = new RegionInfo + { + Index = region.Index, + Color = region.Color, + ImageRectangle = region.ImageRectangle, + ControlRectangle = region.ControlRectangle + }; + + // 添加到_drawnRectangles + _drawnRectangles.Add(drawnZone); + } + } + /// /// 鼠标释放事件 - 完成矩形绘制、调整大小或移动 /// 使用增量绘制,避免每次都重绘所有矩形 @@ -2713,6 +2912,9 @@ namespace JoyD.Windows.CS _drawnRectangles.Add(regionInfo); + // 从_drawnRectangles同步到原始测温区列表和绝对测温区列表 + SyncTemperatureZonesFromDrawnRectangles(); + // 添加区域后更新区域编号显示(使用绘制状态) UpdateButtonsVisibility(2); @@ -3601,14 +3803,20 @@ namespace JoyD.Windows.CS { // 仅在非设计模式下启动定时器 if (!DesignMode) - { - _timer.Start(); - - // 立即执行一次定时器事件,避免首次显示时的延迟 - Timer_Tick(sender, e); - + { // 在窗口完全显示后重新计算工具栏尺寸,确保所有按钮都能正确显示在多行中 AdjustToolStripDimensions(); + + // 从_drawnRectangles同步到原始测温区列表和绝对测温区列表 + SyncTemperatureZonesFromDrawnRectangles(); + + // 重新创建叠加层图像,确保测温区和温差图正确显示 + if (_rectangleOverlayImage != null) + { + _rectangleOverlayImage.Dispose(); + _rectangleOverlayImage = null; + } + CreateRectangleOverlayImage(); } } @@ -3692,6 +3900,9 @@ namespace JoyD.Windows.CS // 用读取的颜色填充叠加层图像对应的区域 CreateRectangleOverlayImage(); + // 从_drawnRectangles同步到原始测温区列表和绝对测温区列表 + SyncTemperatureZonesFromDrawnRectangles(); + // 触发重绘 picBoxTemp.Invalidate(); @@ -3931,6 +4142,9 @@ namespace JoyD.Windows.CS { _drawnRectangles.Remove(regionToRemove); + // 从_drawnRectangles同步到原始测温区列表和绝对测温区列表 + SyncTemperatureZonesFromDrawnRectangles(); + // 取消选中状态 _selectedRegionIndex = -1; @@ -3951,8 +4165,6 @@ namespace JoyD.Windows.CS /// private void Setting_FormClosing(object sender, FormClosingEventArgs e) { - _timer.Stop(); - // 当自动配置为true时,保存回加载时的文件 if (_autoConfig && !string.IsNullOrEmpty(_projectPath)) { @@ -4332,7 +4544,7 @@ namespace JoyD.Windows.CS // 检查是否点击在某个区域内 bool clickedOnRegion = false; - foreach (RegionInfo region in _drawnRectangles) + foreach (RegionInfo region in _absoluteTemperatureZones) { if (region.ImageRectangle.Contains(imagePoint)) { @@ -4460,34 +4672,6 @@ namespace JoyD.Windows.CS { UpdateOverlayForSizeChange(); } - - private void Timer_Tick(object sender, EventArgs e) - { - // 这里可以添加每秒需要执行的代码 - // 例如:更新界面数据、检查状态等 - if (DesignMode || this.IsDisposed || this.Disposing) - return; - - // 线程安全检查 - 确保在UI线程上执行 - if (this.InvokeRequired) - { - try - { - this.BeginInvoke(new Action(() => - { - // 直接在这里实现更新图像的逻辑 - })); - } - catch (ObjectDisposedException) - { - // 控件已释放,忽略 - } - return; - } - - // 直接实现更新图像的逻辑 - } - /// /// 更新pictureBoxTemperatureDisplay的图像 /// 此方法可以从任何线程调用 @@ -5091,6 +5275,19 @@ namespace JoyD.Windows.CS _detectionZone.Height = _tempDetectionZone.Height; _detectionZone.Color = _tempDetectionZone.Color; // 保存检测区颜色 + // 检测区发生变化,更新绝对测温区 + UpdateAbsoluteTemperatureZones(); + + // 更新绝对温差图数据 + UpdateAbsoluteTempDiffData(); + + // 正确释放叠加层资源后设为 null + if (_rectangleOverlayImage != null) + { + _rectangleOverlayImage.Dispose(); + _rectangleOverlayImage = null; + } + // 恢复叠加层绘制,显示测温区和温差图 CreateRectangleOverlayImage();