测温区显示时坐标转换

This commit is contained in:
zqm
2026-01-09 14:31:44 +08:00
parent b4fcdc9289
commit e7f9985c45

View File

@@ -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<RegionInfo> _drawnRectangles = new List<RegionInfo>();
// 原始测温区列表(相对于检测区的位置)
private List<RegionInfo> _originalTemperatureZones = new List<RegionInfo>();
// 绝对测温区列表(相对于整个图像的位置,用于绘制和交互)
private List<RegionInfo> _absoluteTemperatureZones = new List<RegionInfo>();
// 原始温差图数据(相对于检测区的位置)
private Dictionary<Point, double> _originalTempDiffData = new Dictionary<Point, double>();
// 绝对温差图数据(相对于整个图像的位置,用于绘制和交互)
private Dictionary<Point, double> _absoluteTempDiffData = new Dictionary<Point, double>();
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
}
}
/// <summary>
/// 根据原始测温区和当前检测区,更新绝对测温区列表
/// </summary>
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);
}
}
/// <summary>
/// 根据原始温差图数据和当前检测区,更新绝对温差图数据
/// </summary>
private void UpdateAbsoluteTempDiffData()
{
// 清空绝对温差图数据
_absoluteTempDiffData.Clear();
// 遍历原始温差图数据,计算绝对位置并添加到绝对温差图数据
foreach (KeyValuePair<Point, double> originalPoint in _originalTempDiffData)
{
// 计算绝对位置
Point absolutePoint = new Point(
_detectionZone.X + originalPoint.Key.X,
_detectionZone.Y + originalPoint.Key.Y
);
// 添加到绝对温差图数据
_absoluteTempDiffData[absolutePoint] = originalPoint.Value;
}
}
/// <summary>
/// 从绝对测温区更新原始测温区列表
/// </summary>
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);
}
}
/// <summary>
/// 从_drawnRectangles同步到原始测温区列表和绝对测温区列表
/// 用于初始化和加载测温区时
/// </summary>
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();
}
/// <summary>
/// 从绝对测温区列表同步到_drawnRectangles
/// 用于绝对测温区发生变化时
/// </summary>
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);
}
}
/// <summary>
/// 鼠标释放事件 - 完成矩形绘制、调整大小或移动
/// 使用增量绘制,避免每次都重绘所有矩形
@@ -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
/// </summary>
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;
}
// 直接实现更新图像的逻辑
}
/// <summary>
/// 更新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();