优化温度显示逻辑

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.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
@@ -87,7 +85,7 @@ namespace JoyD.Windows.CS.Toprie
private string _projectPath = "";
// 加载的测温区配置
private List<TemperatureZone> _loadedTemperatureZones = new List<TemperatureZone>();
private readonly List<TemperatureZone> _loadedTemperatureZones = new List<TemperatureZone>();
// 加载的温差配置
private TemperatureDiffConfig _loadedTemperatureDiffConfig = new TemperatureDiffConfig();
@@ -154,18 +152,17 @@ namespace JoyD.Windows.CS.Toprie
try
{
// 解析颜色支持HTML格式和十六进制格式
TemperatureZone zone = new TemperatureZone
{
Index = int.Parse(parts[0]),
X = int.Parse(parts[1]),
Y = int.Parse(parts[2]),
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);
}
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以显示状态信息
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
{
@@ -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在暂停状态下会显示暂停信息
@@ -2039,10 +2036,7 @@ namespace JoyD.Windows.CS.Toprie
}
// 释放组件资源
if (components != null)
{
components.Dispose();
}
components?.Dispose();
}
base.Dispose(disposing);
}
@@ -2791,6 +2785,64 @@ namespace JoyD.Windows.CS.Toprie
/// 实现温度数据及其他实时信息的显示功能
/// 根据README.md要求实现10项功能
/// </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()
{
lock (_displayImageLock)
@@ -2862,65 +2914,12 @@ namespace JoyD.Windows.CS.Toprie
if (temperatureTexts.Count == 0)
return;
// 设置文本样式
Font font = new Font("微软雅黑", 12, FontStyle.Bold);
Brush brush = new SolidBrush(Color.White);
StringFormat format = new StringFormat
{
Alignment = StringAlignment.Near, // 左对齐
LineAlignment = StringAlignment.Center
};
// 将List<string>转换为string[]以便传递给DrawTextInAreaCentered方法
string[] textsArray = temperatureTexts.ToArray();
// 计算文本区域大小
SizeF[] textSizes = new SizeF[temperatureTexts.Count];
float maxTextWidth = 0;
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();
// 调用DrawTextInAreaCentered方法绘制温度文本
// 根据温度显示模式,使用不同的参数
DrawTextInAreaCentered(g, textsArray);
}
// 设置显示状态标志

View File

@@ -8,11 +8,6 @@ using System.Net.Sockets;
using System.IO;
using System.Threading;
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
{
@@ -212,7 +207,7 @@ namespace JoyD.Windows.CS.Toprie
private List<string> _deviceIds = new List<string>();
// 设备信息列表
private List<DeviceInfo> _deviceList = new List<DeviceInfo>();
private readonly List<DeviceInfo> _deviceList = new List<DeviceInfo>();
// 目标设备ID用于指定ID连接
private readonly int _targetDeviceId = -1;
@@ -224,7 +219,7 @@ namespace JoyD.Windows.CS.Toprie
private int _devicePort = 8080;
// 加载的测温区配置
private List<TemperatureZone> _loadedTemperatureZones = new List<TemperatureZone>();
private readonly List<TemperatureZone> _loadedTemperatureZones = new List<TemperatureZone>();
// 加载的温差配置
private TemperatureDiffConfig _loadedTemperatureDiffConfig = new TemperatureDiffConfig();
@@ -241,8 +236,8 @@ namespace JoyD.Windows.CS.Toprie
private readonly bool _isDisposed = false;
// 图像模式
private ImageMode _currentImageMode = ImageMode.Infrared;
// 温度数据处理锁,用于防止并发处理温度数据
private readonly object _temperatureProcessingLock = new object();
// 当前色彩模式
private PaletteType _currentPaletteType = PaletteType.WhiteHot;
// 当前视频模式
@@ -425,18 +420,17 @@ namespace JoyD.Windows.CS.Toprie
try
{
// 解析颜色支持HTML格式和十六进制格式
TemperatureZone zone = new TemperatureZone
{
Index = int.Parse(parts[0]),
X = int.Parse(parts[1]),
Y = int.Parse(parts[2]),
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);
}
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}");
bool statusChanged = (_connectionStatus != newStatus);
bool statusChanged = _connectionStatus != newStatus;
ConnectionStatus oldStatus = _connectionStatus;
if (statusChanged)
@@ -659,8 +653,8 @@ namespace JoyD.Windows.CS.Toprie
// 保存状态变更相关信息供后续处理
ConnectionStatus finalNewStatus = newStatus;
bool shouldReconnect = (newStatus == ConnectionStatus.Disconnected && _isAutoReconnectEnabled && oldStatus != ConnectionStatus.Connecting);
bool shouldReset = (newStatus == ConnectionStatus.Connected);
bool shouldReconnect = newStatus == ConnectionStatus.Disconnected && _isAutoReconnectEnabled && oldStatus != ConnectionStatus.Connecting;
bool shouldReset = newStatus == ConnectionStatus.Connected;
// 添加状态转换验证,避免不合理的状态切换
bool isValidTransition = ValidateStatusTransition(oldStatus, newStatus);
@@ -2070,7 +2064,7 @@ namespace JoyD.Windows.CS.Toprie
// 根据SDK文档从头部中获取payload_length
// 假设payload_length在头部中的特定位置例如第5-8字节
// 注意:需要根据实际的头部结构修改此实现
int payloadLength = 0;
int payloadLength;
try
{
@@ -3058,10 +3052,7 @@ namespace JoyD.Windows.CS.Toprie
{
_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];
int startIndex = (quoteChar == '"' || quoteChar == '\'') ? boundaryIndex + 1 : boundaryIndex;
int endIndex = -1;
int endIndex;
if (startIndex > boundaryIndex)
{
@@ -3679,9 +3670,8 @@ namespace JoyD.Windows.CS.Toprie
/// </summary>
/// <param name="buffer">数据缓冲区</param>
/// <param name="boundary">multipart boundary</param>
/// <param name="imageDataBuffer">原始图像数据缓冲区</param>
/// <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);
int startPos = 0;
@@ -4135,7 +4125,7 @@ namespace JoyD.Windows.CS.Toprie
// 再次读取当前值进行验证不依赖SetColorPlate的返回值
int currentValue = _a8Sdk.GetColorPlate();
Log($"验证读取到的当前色彩模式值: {currentValue},目标值: {paletteValue}");
setSuccess = (currentValue == paletteValue);
setSuccess = currentValue == paletteValue;
// 如果设置成功,更新内部状态
if (setSuccess)
@@ -4805,10 +4795,7 @@ namespace JoyD.Windows.CS.Toprie
finally
{
// 确保即使发生异常,也停止定时器
if (timeoutTimer != null)
{
timeoutTimer.Dispose();
}
timeoutTimer?.Dispose();
}
}
catch (Exception ex)
@@ -5868,7 +5855,7 @@ namespace JoyD.Windows.CS.Toprie
{
// 写入CSV头部和元信息
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($"# 修正分辨率: {FixedWidth}x{FixedHeight}");
writer.WriteLine($"# 最高温度: {temperatureData.MaxTemperature:F2}°C");
@@ -6079,14 +6066,8 @@ namespace JoyD.Windows.CS.Toprie
{
try
{
if (stream != null)
{
stream.Close();
}
if (tcpClient != null)
{
tcpClient.Close();
}
stream?.Close();
tcpClient?.Close();
}
catch (Exception ex)
{