diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs b/Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs
index 53061e7..8fd26b5 100644
--- a/Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs
+++ b/Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs
@@ -80,7 +80,7 @@ namespace JoyD.Windows.CS.Toprie
}
///
- /// 解析原始温度数据
+ /// 解析原始温度数据,支持根据数据长度自适应宽高
///
/// 原始温度数据
/// 温度补偿值
@@ -104,39 +104,62 @@ namespace JoyD.Windows.CS.Toprie
throw new ArgumentException("温度数据头部信息无效");
}
+ // 从头部解析温度数据长度
+ int payloadLength = GetPayloadLengthFromHeader(rawData);
+ int actualDataLength = rawData.Length - 24; // 实际温度数据长度(总长度减去头部长度)
+
+ // 验证数据长度一致性
+ if (payloadLength > 0 && payloadLength != actualDataLength)
+ {
+ System.Diagnostics.Debug.WriteLine($"警告: 头部指定的数据长度({payloadLength})与实际数据长度({actualDataLength})不匹配");
+ // 但我们仍然使用实际数据长度继续处理
+ }
+
+ // 根据数据长度自适应确定宽高
+ int pixelCount = actualDataLength / 2; // 每个像素点2字节
+ int[] widthHeight = GetWidthHeightByPixelCount(pixelCount);
+ int adaptiveWidth = widthHeight[0];
+ int adaptiveHeight = widthHeight[1];
+
+ // 输出自适应宽高信息
+ System.Diagnostics.Debug.WriteLine($"根据数据长度自适应宽高: {adaptiveWidth}x{adaptiveHeight} (像素数: {pixelCount})");
+
+ // 如果自适应宽高与传入的宽高不同,更新宽高并重新初始化矩阵
+ bool isAdaptiveResolution = false;
+ if (adaptiveWidth != Width || adaptiveHeight != Height)
+ {
+ isAdaptiveResolution = true;
+ Width = adaptiveWidth;
+ Height = adaptiveHeight;
+ TemperatureMatrix = new float[Height, Width];
+ System.Diagnostics.Debug.WriteLine($"注意: 使用自适应宽高替换了原始宽高设置");
+ }
+
// 跳过24字节的头部信息
int dataIndex = 24;
- // 确保跳过头部后仍有足够的数据用于解析
- int requiredDataLength = Width * Height * 2; // 每个温度点2字节
- if (rawData.Length - dataIndex < requiredDataLength)
- {
- System.Diagnostics.Debug.WriteLine($"警告: 数据长度不足,需要{requiredDataLength}字节温度数据,但实际只有{rawData.Length - dataIndex}字节");
- throw new ArgumentException("原始数据长度不足以包含完整的温度数据");
- }
+ // 计算最大可处理的像素数
+ int maxPixels = Math.Min(pixelCount, Width * Height);
// 遍历所有像素点,按顺序处理温度数据
- for (int row = 0; row < Height; row++)
+ for (int row = 0; row < Height && dataIndex + 1 < rawData.Length; row++)
{
- for (int col = 0; col < Width; col++)
+ for (int col = 0; col < Width && dataIndex + 1 < rawData.Length; col++)
{
- if (dataIndex + 1 < rawData.Length)
- {
- // 按照SDK实际实现计算温度值:摄氏温度=(L + H*256 - 2730)/10
- // 注意:SDK实现是低字节在前,高字节在后,且包含2730的开尔文到摄氏度转换
- int lowByte = rawData[dataIndex];
- int highByte = rawData[dataIndex + 1];
- float rawTemperature = (lowByte + highByte * 256 - 2730) / 10.0f;
- float compensatedTemperature = rawTemperature + compensationValue;
-
- // 原始温度存入TemperatureMatrix(未温补)
- TemperatureMatrix[row, col] = rawTemperature;
-
- // 温补后的温度存入RealTemperatureMatrix(映射到512×384矩阵)
- MapToRealTemperatureMatrix(row, col, compensatedTemperature);
-
- dataIndex += 2;
- }
+ // 按照SDK实际实现计算温度值:摄氏温度=(L + H*256 - 2730)/10
+ // 注意:SDK实现是低字节在前,高字节在后,且包含2730的开尔文到摄氏度转换
+ int lowByte = rawData[dataIndex];
+ int highByte = rawData[dataIndex + 1];
+ float rawTemperature = (lowByte + highByte * 256 - 2730) / 10.0f;
+ float compensatedTemperature = rawTemperature + compensationValue;
+
+ // 原始温度存入TemperatureMatrix(未温补)
+ TemperatureMatrix[row, col] = rawTemperature;
+
+ // 温补后的温度存入RealTemperatureMatrix(映射到512×384矩阵)
+ MapToRealTemperatureMatrix(row, col, compensatedTemperature);
+
+ dataIndex += 2;
}
}
}
@@ -326,30 +349,81 @@ namespace JoyD.Windows.CS.Toprie
/// 如果头部信息有效返回true,否则返回false
private bool ValidateHeader(byte[] rawData)
{
- // 根据SDK文档,头部信息的前几个字节通常包含标识字符或特定模式
- // 这里实现基本验证,可以根据SDK文档的具体规范进行扩展
+ // 根据SDK文档,头部信息的前几个字节包含标识字符和数据长度
// 检查原始数据不为空且长度足够
if (rawData == null || rawData.Length < 24)
return false;
- // 示例验证逻辑:可以根据实际SDK文档中的头部格式规范进行调整
- // 1. 检查数据长度是否合理(至少包含头部+最小温度数据)
+ // 1. 验证头部标识字符是否为"+TEMP"
+ string headerMark = Encoding.ASCII.GetString(rawData, 0, 5).TrimEnd('\0');
+ if (headerMark != "+TEMP")
+ {
+ System.Diagnostics.Debug.WriteLine($"警告: 头部标识不匹配,期望'+TEMP',实际为'{headerMark}'");
+ return false;
+ }
+
+ // 2. 检查数据长度是否合理(至少包含头部+最小温度数据)
if (rawData.Length < 24 + 2) // 24字节头部 + 至少1个温度点(2字节)
return false;
- // 2. 如果SDK文档中定义了特定的头部标识,可以在这里验证
- // 例如:检查前4个字节是否为特定的魔术数字
- // uint magicNumber = BitConverter.ToUInt32(rawData, 0);
- // if (magicNumber != 0x12345678) // 假设的魔术数字
- // return false;
-
- // 3. 可以验证头部中的某些字段是否在合理范围内
- // 例如:宽度、高度等信息
-
- // 目前实现的是基本验证,根据实际SDK规范可以扩展更详细的验证逻辑
return true;
}
+
+ ///
+ /// 从头部解析温度数据长度
+ ///
+ /// 包含头部信息的原始数据
+ /// 温度数据长度(字节数)
+ private int GetPayloadLengthFromHeader(byte[] rawData)
+ {
+ // 根据SDK文档,payload_length在头部的第5-8字节
+ // 注意:SDK文档指出采用低字节在前的存储方式
+ if (rawData.Length >= 9)
+ {
+ return BitConverter.ToInt32(rawData, 5);
+ }
+ return 0;
+ }
+
+ ///
+ /// 根据像素数量和已知分辨率比例推算宽高
+ ///
+ /// 像素总数
+ /// 宽高数组,格式为[宽度, 高度]
+ private int[] GetWidthHeightByPixelCount(int pixelCount)
+ {
+ // 已知设备支持的分辨率比例为4:3
+ // 检查是否为标准分辨率:
+ // 240×180 = 43200像素
+ // 384×288 = 110592像素
+
+ // 标准分辨率映射
+ var standardResolutions = new Dictionary {
+ { 43200, new int[] { 240, 180 } },
+ { 110592, new int[] { 384, 288 } }
+ };
+
+ // 如果匹配标准分辨率,安全地返回对应值
+ int[] resolution;
+ if (standardResolutions.TryGetValue(pixelCount, out resolution))
+ {
+ return resolution;
+ }
+
+ // 否则尝试根据像素数推算最接近4:3比例的宽高
+ float ratio = 4.0f / 3.0f;
+ int width = (int)Math.Sqrt(pixelCount * ratio);
+ int height = (int)(width / ratio);
+
+ // 确保宽高相乘尽可能接近像素数
+ while (width * height < pixelCount && width * (height + 1) <= pixelCount)
+ {
+ height++;
+ }
+
+ return new int[] { width, height };
+ }
}
///