优化温度显示逻辑

This commit is contained in:
zqm
2026-01-04 10:32:16 +08:00
parent c448c361c9
commit 3f6abcc130
2 changed files with 90 additions and 110 deletions

View File

@@ -1,10 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using System.Threading; using System.Threading;
@@ -87,7 +85,7 @@ namespace JoyD.Windows.CS.Toprie
private string _projectPath = ""; private string _projectPath = "";
// 加载的测温区配置 // 加载的测温区配置
private List<TemperatureZone> _loadedTemperatureZones = new List<TemperatureZone>(); private readonly List<TemperatureZone> _loadedTemperatureZones = new List<TemperatureZone>();
// 加载的温差配置 // 加载的温差配置
private TemperatureDiffConfig _loadedTemperatureDiffConfig = new TemperatureDiffConfig(); private TemperatureDiffConfig _loadedTemperatureDiffConfig = new TemperatureDiffConfig();
@@ -154,18 +152,17 @@ namespace JoyD.Windows.CS.Toprie
try try
{ {
// 解析颜色支持HTML格式和十六进制格式
TemperatureZone zone = new TemperatureZone TemperatureZone zone = new TemperatureZone
{ {
Index = int.Parse(parts[0]), Index = int.Parse(parts[0]),
X = int.Parse(parts[1]), X = int.Parse(parts[1]),
Y = int.Parse(parts[2]), Y = int.Parse(parts[2]),
Width = int.Parse(parts[3]), Width = int.Parse(parts[3]),
Height = int.Parse(parts[4]) Height = int.Parse(parts[4]),
Color = ColorTranslator.FromHtml(parts[5])
}; };
// 解析颜色支持HTML格式和十六进制格式
zone.Color = ColorTranslator.FromHtml(parts[5]);
_loadedTemperatureZones.Add(zone); _loadedTemperatureZones.Add(zone);
} }
catch (Exception ex) catch (Exception ex)
@@ -384,7 +381,7 @@ namespace JoyD.Windows.CS.Toprie
} }
// 设置显示标志 // 设置显示标志
_isDisplayingInfo = (isPaused || isDisconnected || isReconnecting || _showGlobalTemperature || _showAreaTemperature); _isDisplayingInfo = isPaused || isDisconnected || isReconnecting || _showGlobalTemperature || _showAreaTemperature;
// 步骤3无论就绪状态如何都调用更新UI以显示状态信息 // 步骤3无论就绪状态如何都调用更新UI以显示状态信息
UpdateImageOnUI(); UpdateImageOnUI();
@@ -433,7 +430,7 @@ namespace JoyD.Windows.CS.Toprie
} }
} }
Console.WriteLine($"[PauseDetection] 检测已暂停 - DeviceManager状态更新完成当前时间: {DateTime.Now.ToString("HH:mm:ss.fff")}"); Console.WriteLine($"[PauseDetection] 检测已暂停 - DeviceManager状态更新完成当前时间: {DateTime.Now:HH:mm:ss.fff}");
} }
else else
{ {
@@ -462,7 +459,7 @@ namespace JoyD.Windows.CS.Toprie
} }
} }
Console.WriteLine($"[PauseDetection] 检测已恢复 - DeviceManager状态更新完成连接状态: {_deviceManager?.ConnectionStatus}, 当前时间: {DateTime.Now.ToString("HH:mm:ss.fff")}"); Console.WriteLine($"[PauseDetection] 检测已恢复 - DeviceManager状态更新完成连接状态: {_deviceManager?.ConnectionStatus}, 当前时间: {DateTime.Now:HH:mm:ss.fff}");
} }
// 修改流程第1点和第5点暂停或恢复时设置暂停状态调用更新Info在暂停状态下会显示暂停信息 // 修改流程第1点和第5点暂停或恢复时设置暂停状态调用更新Info在暂停状态下会显示暂停信息
@@ -2039,10 +2036,7 @@ namespace JoyD.Windows.CS.Toprie
} }
// 释放组件资源 // 释放组件资源
if (components != null) components?.Dispose();
{
components.Dispose();
}
} }
base.Dispose(disposing); base.Dispose(disposing);
} }
@@ -2791,6 +2785,64 @@ namespace JoyD.Windows.CS.Toprie
/// 实现温度数据及其他实时信息的显示功能 /// 实现温度数据及其他实时信息的显示功能
/// 根据README.md要求实现10项功能 /// 根据README.md要求实现10项功能
/// </summary> /// </summary>
/// <summary>
/// 在指定区域内居中显示文本
/// </summary>
/// <param name="g">用于绘制的Graphics对象</param>
/// <param name="texts">要显示的文本数组</param>
/// <param name="color">文本颜色,默认为白色</param>
/// <param name="area">显示文本的区域默认为null此时使用整个图像框</param>
private void DrawTextInAreaCentered(Graphics g, string[] texts, Color? color = null, RectangleF? area = null)
{
if (g == null || texts == null || texts.Length == 0)
return;
// 设置默认颜色为白色
Color displayColor = color ?? Color.White;
// 创建固定的字体和格式对象
using (Font font = new Font("微软雅黑", 12, FontStyle.Bold))
using (Brush brush = new SolidBrush(displayColor))
{
StringFormat format = new StringFormat
{
Alignment = StringAlignment.Near, // 左对齐
LineAlignment = StringAlignment.Center // 垂直居中
};
// 如果没有指定区域,使用整个图像框作为默认区域
RectangleF displayArea = area ?? new RectangleF(0, 0, _displayImage.Width, _displayImage.Height);
// 计算文本区域大小
SizeF[] textSizes = new SizeF[texts.Length];
float maxTextWidth = 0;
float totalTextHeight = 0;
const float lineSpacing = 5; // 行间距
for (int i = 0; i < texts.Length; i++)
{
textSizes[i] = g.MeasureString(texts[i], font);
maxTextWidth = Math.Max(maxTextWidth, textSizes[i].Width);
totalTextHeight += textSizes[i].Height;
}
// 添加文本间距
totalTextHeight += (texts.Length - 1) * lineSpacing;
// 计算文本在区域内的居中位置
float textAreaX = displayArea.X + (displayArea.Width - maxTextWidth) / 2;
float textAreaY = displayArea.Y + (displayArea.Height - totalTextHeight) / 2;
// 绘制温度文本
float currentY = textAreaY;
for (int i = 0; i < texts.Length; i++)
{
g.DrawString(texts[i], font, brush, textAreaX, currentY, format);
currentY += textSizes[i].Height + lineSpacing; // 加上行间距
}
}
}
private void UpdateRealTimeInfoOnUI() private void UpdateRealTimeInfoOnUI()
{ {
lock (_displayImageLock) lock (_displayImageLock)
@@ -2862,65 +2914,12 @@ namespace JoyD.Windows.CS.Toprie
if (temperatureTexts.Count == 0) if (temperatureTexts.Count == 0)
return; return;
// 设置文本样式 // 将List<string>转换为string[]以便传递给DrawTextInAreaCentered方法
Font font = new Font("微软雅黑", 12, FontStyle.Bold); string[] textsArray = temperatureTexts.ToArray();
Brush brush = new SolidBrush(Color.White);
StringFormat format = new StringFormat
{
Alignment = StringAlignment.Near, // 左对齐
LineAlignment = StringAlignment.Center
};
// 计算文本区域大小 // 调用DrawTextInAreaCentered方法绘制温度文本
SizeF[] textSizes = new SizeF[temperatureTexts.Count]; // 根据温度显示模式,使用不同的参数
float maxTextWidth = 0; DrawTextInAreaCentered(g, textsArray);
float totalTextHeight = 0;
for (int i = 0; i < temperatureTexts.Count; i++)
{
textSizes[i] = g.MeasureString(temperatureTexts[i], font);
maxTextWidth = Math.Max(maxTextWidth, textSizes[i].Width);
totalTextHeight += textSizes[i].Height;
}
// 添加文本间距
totalTextHeight += (temperatureTexts.Count - 1) * 5; // 5像素行间距
// 9. 如果是全局温度时,最低温度和最高温度、平均温度,显示三行(左对齐),整体水平和垂直相对于图像框居中显示
if (isGlobalTemperatureMode)
{
// 计算文本区域的位置(整体居中)
float textAreaX = (_displayImage.Width - maxTextWidth) / 2;
float textAreaY = (_displayImage.Height - totalTextHeight) / 2;
// 绘制温度文本
float currentY = textAreaY;
for (int i = 0; i < temperatureTexts.Count; i++)
{
g.DrawString(temperatureTexts[i], font, brush, textAreaX, currentY, format);
currentY += textSizes[i].Height + 5; // 加上行间距
}
}
// 10. 如果是区域温度时,最低温度和最高温度、平均温度,显示三行(左对齐)
// 由于无法获取区域框信息,临时使用全局居中显示
else if (_showAreaTemperature)
{
// 计算文本区域的位置(整体居中显示)
float textAreaX = (_displayImage.Width - maxTextWidth) / 2;
float textAreaY = (_displayImage.Height - totalTextHeight) / 2;
// 绘制温度文本
float currentY = textAreaY;
for (int i = 0; i < temperatureTexts.Count; i++)
{
g.DrawString(temperatureTexts[i], font, brush, textAreaX, currentY, format);
currentY += textSizes[i].Height + 5; // 加上行间距
}
}
// 释放资源
font.Dispose();
brush.Dispose();
format.Dispose();
} }
// 设置显示状态标志 // 设置显示状态标志

View File

@@ -8,11 +8,6 @@ using System.Net.Sockets;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Net.NetworkInformation;
namespace JoyD.Windows.CS.Toprie namespace JoyD.Windows.CS.Toprie
{ {
@@ -212,7 +207,7 @@ namespace JoyD.Windows.CS.Toprie
private List<string> _deviceIds = new List<string>(); private List<string> _deviceIds = new List<string>();
// 设备信息列表 // 设备信息列表
private List<DeviceInfo> _deviceList = new List<DeviceInfo>(); private readonly List<DeviceInfo> _deviceList = new List<DeviceInfo>();
// 目标设备ID用于指定ID连接 // 目标设备ID用于指定ID连接
private readonly int _targetDeviceId = -1; private readonly int _targetDeviceId = -1;
@@ -224,7 +219,7 @@ namespace JoyD.Windows.CS.Toprie
private int _devicePort = 8080; private int _devicePort = 8080;
// 加载的测温区配置 // 加载的测温区配置
private List<TemperatureZone> _loadedTemperatureZones = new List<TemperatureZone>(); private readonly List<TemperatureZone> _loadedTemperatureZones = new List<TemperatureZone>();
// 加载的温差配置 // 加载的温差配置
private TemperatureDiffConfig _loadedTemperatureDiffConfig = new TemperatureDiffConfig(); private TemperatureDiffConfig _loadedTemperatureDiffConfig = new TemperatureDiffConfig();
@@ -241,8 +236,8 @@ namespace JoyD.Windows.CS.Toprie
private readonly bool _isDisposed = false; private readonly bool _isDisposed = false;
// 图像模式 // 图像模式
private ImageMode _currentImageMode = ImageMode.Infrared; private ImageMode _currentImageMode = ImageMode.Infrared;
// 温度数据处理锁,用于防止并发处理温度数据
private readonly object _temperatureProcessingLock = new object();
// 当前色彩模式 // 当前色彩模式
private PaletteType _currentPaletteType = PaletteType.WhiteHot; private PaletteType _currentPaletteType = PaletteType.WhiteHot;
// 当前视频模式 // 当前视频模式
@@ -425,18 +420,17 @@ namespace JoyD.Windows.CS.Toprie
try try
{ {
// 解析颜色支持HTML格式和十六进制格式
TemperatureZone zone = new TemperatureZone TemperatureZone zone = new TemperatureZone
{ {
Index = int.Parse(parts[0]), Index = int.Parse(parts[0]),
X = int.Parse(parts[1]), X = int.Parse(parts[1]),
Y = int.Parse(parts[2]), Y = int.Parse(parts[2]),
Width = int.Parse(parts[3]), Width = int.Parse(parts[3]),
Height = int.Parse(parts[4]) Height = int.Parse(parts[4]),
Color = ColorTranslator.FromHtml(parts[5])
}; };
// 解析颜色支持HTML格式和十六进制格式
zone.Color = ColorTranslator.FromHtml(parts[5]);
_loadedTemperatureZones.Add(zone); _loadedTemperatureZones.Add(zone);
} }
catch (Exception ex) catch (Exception ex)
@@ -626,7 +620,7 @@ namespace JoyD.Windows.CS.Toprie
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] UpdateConnectionStatus() - 尝试更新状态: {_connectionStatus} -> {newStatus}, 消息: {message}"); Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] UpdateConnectionStatus() - 尝试更新状态: {_connectionStatus} -> {newStatus}, 消息: {message}");
bool statusChanged = (_connectionStatus != newStatus); bool statusChanged = _connectionStatus != newStatus;
ConnectionStatus oldStatus = _connectionStatus; ConnectionStatus oldStatus = _connectionStatus;
if (statusChanged) if (statusChanged)
@@ -659,8 +653,8 @@ namespace JoyD.Windows.CS.Toprie
// 保存状态变更相关信息供后续处理 // 保存状态变更相关信息供后续处理
ConnectionStatus finalNewStatus = newStatus; ConnectionStatus finalNewStatus = newStatus;
bool shouldReconnect = (newStatus == ConnectionStatus.Disconnected && _isAutoReconnectEnabled && oldStatus != ConnectionStatus.Connecting); bool shouldReconnect = newStatus == ConnectionStatus.Disconnected && _isAutoReconnectEnabled && oldStatus != ConnectionStatus.Connecting;
bool shouldReset = (newStatus == ConnectionStatus.Connected); bool shouldReset = newStatus == ConnectionStatus.Connected;
// 添加状态转换验证,避免不合理的状态切换 // 添加状态转换验证,避免不合理的状态切换
bool isValidTransition = ValidateStatusTransition(oldStatus, newStatus); bool isValidTransition = ValidateStatusTransition(oldStatus, newStatus);
@@ -2070,7 +2064,7 @@ namespace JoyD.Windows.CS.Toprie
// 根据SDK文档从头部中获取payload_length // 根据SDK文档从头部中获取payload_length
// 假设payload_length在头部中的特定位置例如第5-8字节 // 假设payload_length在头部中的特定位置例如第5-8字节
// 注意:需要根据实际的头部结构修改此实现 // 注意:需要根据实际的头部结构修改此实现
int payloadLength = 0; int payloadLength;
try try
{ {
@@ -3058,10 +3052,7 @@ namespace JoyD.Windows.CS.Toprie
{ {
_heartbeatInterval = value; _heartbeatInterval = value;
// 如果已经启用心跳检测,更新定时器 // 如果已经启用心跳检测,更新定时器
if (_heartbeatTimer != null) _heartbeatTimer?.Change(0, _heartbeatInterval);
{
_heartbeatTimer.Change(0, _heartbeatInterval);
}
} }
} }
} }
@@ -3649,7 +3640,7 @@ namespace JoyD.Windows.CS.Toprie
// 处理可能包含引号的情况 // 处理可能包含引号的情况
char quoteChar = contentType[boundaryIndex]; char quoteChar = contentType[boundaryIndex];
int startIndex = (quoteChar == '"' || quoteChar == '\'') ? boundaryIndex + 1 : boundaryIndex; int startIndex = (quoteChar == '"' || quoteChar == '\'') ? boundaryIndex + 1 : boundaryIndex;
int endIndex = -1; int endIndex;
if (startIndex > boundaryIndex) if (startIndex > boundaryIndex)
{ {
@@ -3679,9 +3670,8 @@ namespace JoyD.Windows.CS.Toprie
/// </summary> /// </summary>
/// <param name="buffer">数据缓冲区</param> /// <param name="buffer">数据缓冲区</param>
/// <param name="boundary">multipart boundary</param> /// <param name="boundary">multipart boundary</param>
/// <param name="imageDataBuffer">原始图像数据缓冲区</param>
/// <returns>处理到的位置索引,-1表示未找到完整的图像块</returns> /// <returns>处理到的位置索引,-1表示未找到完整的图像块</returns>
private int ProcessMultipartImageData(byte[] buffer, string boundary, MemoryStream imageDataBuffer) private int ProcessMultipartImageData(byte[] buffer, string boundary)
{ {
byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes(boundary); byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes(boundary);
int startPos = 0; int startPos = 0;
@@ -4135,7 +4125,7 @@ namespace JoyD.Windows.CS.Toprie
// 再次读取当前值进行验证不依赖SetColorPlate的返回值 // 再次读取当前值进行验证不依赖SetColorPlate的返回值
int currentValue = _a8Sdk.GetColorPlate(); int currentValue = _a8Sdk.GetColorPlate();
Log($"验证读取到的当前色彩模式值: {currentValue},目标值: {paletteValue}"); Log($"验证读取到的当前色彩模式值: {currentValue},目标值: {paletteValue}");
setSuccess = (currentValue == paletteValue); setSuccess = currentValue == paletteValue;
// 如果设置成功,更新内部状态 // 如果设置成功,更新内部状态
if (setSuccess) if (setSuccess)
@@ -4805,10 +4795,7 @@ namespace JoyD.Windows.CS.Toprie
finally finally
{ {
// 确保即使发生异常,也停止定时器 // 确保即使发生异常,也停止定时器
if (timeoutTimer != null) timeoutTimer?.Dispose();
{
timeoutTimer.Dispose();
}
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -5868,7 +5855,7 @@ namespace JoyD.Windows.CS.Toprie
{ {
// 写入CSV头部和元信息 // 写入CSV头部和元信息
writer.WriteLine("# 温度数据导出"); writer.WriteLine("# 温度数据导出");
writer.WriteLine($"# 导出时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); writer.WriteLine($"# 导出时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
writer.WriteLine($"# 采样分辨率: {temperatureData.Width}x{temperatureData.Height}"); writer.WriteLine($"# 采样分辨率: {temperatureData.Width}x{temperatureData.Height}");
writer.WriteLine($"# 修正分辨率: {FixedWidth}x{FixedHeight}"); writer.WriteLine($"# 修正分辨率: {FixedWidth}x{FixedHeight}");
writer.WriteLine($"# 最高温度: {temperatureData.MaxTemperature:F2}°C"); writer.WriteLine($"# 最高温度: {temperatureData.MaxTemperature:F2}°C");
@@ -6079,14 +6066,8 @@ namespace JoyD.Windows.CS.Toprie
{ {
try try
{ {
if (stream != null) stream?.Close();
{ tcpClient?.Close();
stream.Close();
}
if (tcpClient != null)
{
tcpClient.Close();
}
} }
catch (Exception ex) catch (Exception ex)
{ {