diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/README.md b/Windows/CS/Framework4.0/Toprie/Toprie/README.md
index 68e766a..8fb4e5c 100644
--- a/Windows/CS/Framework4.0/Toprie/Toprie/README.md
+++ b/Windows/CS/Framework4.0/Toprie/Toprie/README.md
@@ -179,6 +179,11 @@
1. 用透明色清空温差层图像
2. 移除所有已有的温差图例列表
### btnLoadTempDiff(加载温差图)
+1. 弹出用户打开文件对话框,用户选择要加载的csv文件
+2. 用透明色清空温差层图像
+3. 移除所有已有的温差图例列表
+4. 从csv文件中读取所有温差图例信息,添加到温差图例列表中
+5. 从csv文件中读取所有像素的温度值,绘制温差层图像对应的像素
### btnSaveTempDiff(保存温差图)
1. 弹出用户保存文件对话框,用户选择保存路径和文件名
2. 保存温差图例列表中的所有温差图例信息到csv文件
diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Setting.Designer.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Setting.Designer.cs
index f7b6cd8..64d9f80 100644
--- a/Windows/CS/Framework4.0/Toprie/Toprie/Setting.Designer.cs
+++ b/Windows/CS/Framework4.0/Toprie/Toprie/Setting.Designer.cs
@@ -361,6 +361,7 @@ namespace JoyD.Windows.CS
this.btnNewTempDiff.Size = new System.Drawing.Size(23, 4);
this.btnNewTempDiff.Text = "新建温差图";
this.btnNewTempDiff.ToolTipText = "新建温差图";
+ this.btnNewTempDiff.Click += new System.EventHandler(this.BtnNewTempDiff_Click);
//
// btnLoadTempDiff
//
@@ -370,6 +371,7 @@ namespace JoyD.Windows.CS
this.btnLoadTempDiff.Size = new System.Drawing.Size(23, 4);
this.btnLoadTempDiff.Text = "加载温差图";
this.btnLoadTempDiff.ToolTipText = "加载温差图";
+ this.btnLoadTempDiff.Click += new System.EventHandler(this.BtnLoadTempDiff_Click);
//
// btnSaveTempDiff
//
diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs
index 0e093de..b9d27cb 100644
--- a/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs
+++ b/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs
@@ -4173,6 +4173,207 @@ namespace JoyD.Windows.CS
///
/// 保存温差图例按钮点击事件处理程序
///
+ ///
+ /// 新建温差图按钮点击事件处理程序
+ ///
+ private void BtnNewTempDiff_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ // 用透明色清空温差层图像
+ if (_tempDiffOverlayImage != null)
+ {
+ _tempDiffOverlayImage.Dispose();
+ _tempDiffOverlayImage = null;
+ }
+
+ // 确保温差层图像已初始化
+ if (picBoxTemp.Image != null)
+ {
+ InitializeTempDiffOverlayImage();
+ }
+
+ // 移除所有已有的温差图例列表
+ tempDiffData.Clear();
+ dataGridViewTempDiff.Rows.Clear();
+
+ // 更新显示
+ picBoxTemp.Invalidate();
+ MessageBox.Show("已成功创建新的温差图!", "操作成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"新建温差图时发生错误: {ex.Message}");
+ MessageBox.Show($"新建失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+
+ ///
+ /// 加载温差图按钮点击事件处理程序
+ ///
+ private void BtnLoadTempDiff_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ // 弹出用户打开文件对话框,用户选择要加载的csv文件
+ OpenFileDialog openFileDialog = new OpenFileDialog
+ {
+ Filter = "CSV文件 (*.csv)|*.csv|所有文件 (*.*)|*.*",
+ Title = "加载温差图例和温度数据",
+ FileName = "温差数据.csv"
+ };
+
+ if (openFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ // 用透明色清空温差层图像
+ if (_tempDiffOverlayImage != null)
+ {
+ _tempDiffOverlayImage.Dispose();
+ _tempDiffOverlayImage = null;
+ }
+
+ // 确保温差层图像已初始化
+ if (picBoxTemp.Image != null)
+ {
+ InitializeTempDiffOverlayImage();
+ }
+
+ // 移除所有已有的温差图例列表
+ tempDiffData.Clear();
+ dataGridViewTempDiff.Rows.Clear();
+
+ bool readingLegend = false;
+ bool readingPixelData = false;
+ // 使用温度值作为键,颜色作为值的映射表,与保存时保持一致
+ Dictionary tempToColorMap = new Dictionary();
+
+ // 读取CSV文件
+ using (StreamReader reader = new StreamReader(openFileDialog.FileName, Encoding.UTF8))
+ {
+ string line;
+ while ((line = reader.ReadLine()) != null)
+ {
+ line = line.Trim();
+ if (string.IsNullOrEmpty(line))
+ continue;
+
+ // 识别温差图例信息部分
+ if (line == "温差图例信息")
+ {
+ readingLegend = true;
+ readingPixelData = false;
+ reader.ReadLine(); // 跳过表头行
+ continue;
+ }
+
+ // 识别像素温度数据部分
+ if (line == "像素温度数据")
+ {
+ readingLegend = false;
+ readingPixelData = true;
+ reader.ReadLine(); // 跳过表头行
+ continue;
+ }
+
+ // 处理温差图例信息
+ if (readingLegend && _tempDiffOverlayImage is Bitmap)
+ {
+ string[] parts = line.Split(',');
+ if (parts.Length == 2)
+ {
+ try
+ {
+ double temperature = Convert.ToDouble(parts[0]);
+ string colorHex = parts[1].TrimStart('#');
+ Color color = Color.FromArgb(
+ Convert.ToInt32(colorHex.Substring(0, 2), 16),
+ Convert.ToInt32(colorHex.Substring(2, 2), 16),
+ Convert.ToInt32(colorHex.Substring(4, 2), 16)
+ );
+
+ // 添加到温差图例列表
+ int rowIndex = dataGridViewTempDiff.Rows.Add();
+ dataGridViewTempDiff.Rows[rowIndex].Cells["tempDiffValue"].Value = $"{temperature:F1}°C";
+
+ // 保存到tempDiffData列表和映射表
+ Dictionary item = new Dictionary
+ {
+ { "tempDiffValue", $"{temperature:F1}°C" },
+ { "color", color }
+ };
+ tempDiffData.Add(item);
+ tempToColorMap[temperature] = color;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"解析温差图例失败: {ex.Message}");
+ }
+ }
+ }
+
+ // 处理像素温度数据
+ if (readingPixelData && _tempDiffOverlayImage is Bitmap)
+ {
+ string[] parts = line.Split(',');
+ if (parts.Length == 3 && parts[0] != "无温差图像数据")
+ {
+ try
+ {
+ int x = Convert.ToInt32(parts[0]);
+ int y = Convert.ToInt32(parts[1]);
+ double temperature = Convert.ToDouble(parts[2]);
+
+ // 找到对应的颜色 - 必须精确匹配
+ Color pixelColor = Color.Transparent;
+ // 尝试精确匹配
+ if (tempToColorMap.TryGetValue(Math.Round(temperature, 1), out Color exactColor))
+ {
+ pixelColor = exactColor;
+ }
+ else
+ {
+ // 如果没有精确匹配,显示错误并中止加载
+ MessageBox.Show($"温度值 {temperature:F1}°C 在温差图例中找不到精确匹配,请检查温差图例设置!", "加载失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return;
+ }
+
+ if (pixelColor != Color.Transparent)
+ {
+ // 绘制温差层图像对应的像素
+ // 注意:由于保存时是每隔10个像素采样,加载时需要填充这10x10的区域
+ using (Graphics g = Graphics.FromImage(_tempDiffOverlayImage))
+ {
+ using (SolidBrush brush = new SolidBrush(pixelColor))
+ {
+ // 填充10x10的区域
+ g.FillRectangle(brush, x, y, 10, 10);
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"解析像素数据失败: {ex.Message}");
+ }
+ }
+ }
+ }
+ }
+
+ // 更新显示
+ picBoxTemp.Invalidate();
+ MessageBox.Show("温差图已成功加载!", "加载成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"加载温差数据时发生错误: {ex.Message}");
+ MessageBox.Show($"加载失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+
+
+
private void BtnSaveTempDiff_Click(object sender, EventArgs e)
{
try