diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/README.md b/Windows/CS/Framework4.0/Toprie/Toprie/README.md
index 7c609ce..68e766a 100644
--- a/Windows/CS/Framework4.0/Toprie/Toprie/README.md
+++ b/Windows/CS/Framework4.0/Toprie/Toprie/README.md
@@ -180,6 +180,18 @@
2. 移除所有已有的温差图例列表
### btnLoadTempDiff(加载温差图)
### btnSaveTempDiff(保存温差图)
+1. 弹出用户保存文件对话框,用户选择保存路径和文件名
+2. 保存温差图例列表中的所有温差图例信息到csv文件
+3. 每个温差图例信息占一行,格式为:
+ - 温度(如20°C)
+ - 颜色(如#FF0000表示红色)
+4. 保存温差图每个像素的温度值到csv文件
+ - 每个像素温度值占一行,格式为:
+ - X坐标(如100)
+ - Y坐标(如300)
+ - 温度值(°C)(如25.5)
+
+
#### 配置状态说明
1. 初始状态/就绪状态:
diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs
index 6286bc7..0e093de 100644
--- a/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs
+++ b/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs
@@ -1909,28 +1909,62 @@ namespace JoyD.Windows.CS
adjustedBrushSize = Math.Min(adjustedBrushSize, 50); // 最大50像素
}
- using (Pen pen = new Pen(selectedColor, adjustedBrushSize))
- {
+ // 确保1像素画笔在任何缩放比例下都至少保持1像素宽
+ // 对于大于1像素的画笔,继续使用缩放调整
+ int finalBrushSize = _currentBrushSize == 1 ? 1 : adjustedBrushSize;
+
+ using (Pen pen = new Pen(selectedColor, finalBrushSize))
+ {
pen.StartCap = LineCap.Round;
pen.EndCap = LineCap.Round;
pen.LineJoin = LineJoin.Round;
// 如果是首次绘制或上一个点无效,记录当前点作为起点
if (_lastDrawPoint == Point.Empty)
- {
+ {
_lastDrawPoint = imagePoint;
// 绘制起始点的圆形
- int radius = adjustedBrushSize / 2;
+ int radius = finalBrushSize / 2;
g.FillEllipse(new SolidBrush(selectedColor),
imagePoint.X - radius,
imagePoint.Y - radius,
- adjustedBrushSize,
- adjustedBrushSize);
+ finalBrushSize,
+ finalBrushSize);
}
else
- {
- // 绘制连线
- g.DrawLine(pen, _lastDrawPoint, imagePoint);
+ {
+ // 计算两点之间的距离
+ int deltaX = Math.Abs(imagePoint.X - _lastDrawPoint.X);
+ int deltaY = Math.Abs(imagePoint.Y - _lastDrawPoint.Y);
+ int distance = (int)Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
+
+ // 如果距离较大,添加中间点以确保线条连续
+ // 对于1像素画笔,我们需要更密集的点来确保线条流畅
+ if (distance > finalBrushSize * 2 || (_currentBrushSize == 1 && distance > 2))
+ {
+ // 使用 Bresenham 算法的简化版本来绘制连续的线条
+ int steps = Math.Max(deltaX, deltaY);
+ float xIncrement = (float)(imagePoint.X - _lastDrawPoint.X) / steps;
+ float yIncrement = (float)(imagePoint.Y - _lastDrawPoint.Y) / steps;
+
+ Point currentPoint = _lastDrawPoint;
+
+ for (int i = 1; i <= steps; i++)
+ {
+ int nextX = (int)(_lastDrawPoint.X + xIncrement * i);
+ int nextY = (int)(_lastDrawPoint.Y + yIncrement * i);
+ Point nextPoint = new Point(nextX, nextY);
+
+ g.DrawLine(pen, currentPoint, nextPoint);
+ currentPoint = nextPoint;
+ }
+ }
+ else
+ {
+ // 距离较小时,直接绘制连线
+ g.DrawLine(pen, _lastDrawPoint, imagePoint);
+ }
+
// 更新上一个点
_lastDrawPoint = imagePoint;
}
@@ -4112,6 +4146,30 @@ namespace JoyD.Windows.CS
Console.WriteLine("调整toolStrip尺寸失败: " + ex.Message);
}
}
+ ///
+ /// 根据颜色查找对应的温度值
+ ///
+ /// 要查找的颜色
+ /// 对应的温度值,如果没有找到则返回null
+ private double? GetTemperatureByColor(Color color)
+ {
+ // 遍历温差图例数据,查找最接近的颜色
+ foreach (var item in tempDiffData)
+ {
+ Color legendColor = (Color)item["color"];
+
+ // 如果颜色完全匹配
+ if (legendColor.R == color.R && legendColor.G == color.G && legendColor.B == color.B)
+ {
+ string tempString = item["tempDiffValue"].ToString().Replace("°C", "").Trim();
+ return Convert.ToDouble(tempString);
+ }
+ }
+
+ // 如果没有找到完全匹配的颜色,返回null
+ return null;
+ }
+
///
/// 保存温差图例按钮点击事件处理程序
///
@@ -4151,22 +4209,66 @@ namespace JoyD.Windows.CS
writer.WriteLine("像素温度数据");
writer.WriteLine("X坐标,Y坐标,温度值(°C)");
- // 保存温差图每个像素的温度值
- // 这里由于无法直接访问DeviceManager获取温度数据
- // 我们生成一些示例数据用于演示
- // 在实际应用中,应该通过Camera或DeviceManager获取真实的温度数据
- int width = 384; // 假设温度矩阵宽度
- int height = 512; // 假设温度矩阵高度
-
- // 生成示例温度数据(实际应用中应替换为真实数据)
- Random random = new Random();
- for (int y = 0; y < height; y += 10) // 为了减少文件大小,每隔10个像素采样一次
+ // 从_tempDiffOverlayImage中获取真实温度数据
+ if (_tempDiffOverlayImage != null && _tempDiffOverlayImage is Bitmap)
{
- for (int x = 0; x < width; x += 10)
+ Bitmap bitmap = (Bitmap)_tempDiffOverlayImage;
+
+ // 锁定位图以提高性能
+ BitmapData bitmapData = bitmap.LockBits(
+ new Rectangle(0, 0, bitmap.Width, bitmap.Height),
+ ImageLockMode.ReadOnly,
+ PixelFormat.Format32bppArgb);
+
+ try
{
- double tempValue = 20.0 + random.NextDouble() * 30.0; // 生成20-50°C之间的随机温度
- writer.WriteLine($"{x},{y},{tempValue:F1}");
+ int bytesPerPixel = 4; // 32bppArgb格式每像素4字节
+ int byteCount = bitmapData.Stride * bitmapData.Height;
+ byte[] pixels = new byte[byteCount];
+
+ // 将图像数据复制到数组
+ Marshal.Copy(bitmapData.Scan0, pixels, 0, byteCount);
+
+ // 遍历图像像素,每隔10个像素采样一次以减少文件大小
+ for (int y = 0; y < bitmap.Height; y += 10)
+ {
+ for (int x = 0; x < bitmap.Width; x += 10)
+ {
+ // 计算当前像素在数组中的位置
+ int pixelIndex = y * bitmapData.Stride + x * bytesPerPixel;
+
+ // 获取像素颜色
+ byte b = pixels[pixelIndex];
+ byte g = pixels[pixelIndex + 1];
+ byte r = pixels[pixelIndex + 2];
+ byte a = pixels[pixelIndex + 3];
+
+ // 只处理非透明的像素
+ if (a > 0)
+ {
+ Color pixelColor = Color.FromArgb(a, r, g, b);
+ double? temperature = GetTemperatureByColor(pixelColor);
+
+ // 如果找到对应的温度值,则写入文件
+ if (temperature.HasValue)
+ {
+ writer.WriteLine($"{x},{y},{temperature.Value:F1}");
+ }
+ }
+ }
+ }
}
+ finally
+ {
+ // 解锁位图
+ bitmap.UnlockBits(bitmapData);
+ }
+ }
+ else
+ {
+ // 如果没有温差图像数据,提示用户
+ writer.WriteLine("无温差图像数据");
+ MessageBox.Show("警告:未找到温差图像数据,仅保存了温差图例信息。", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}