diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs
index 0d6115a..692378e 100644
--- a/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs
+++ b/Windows/CS/Framework4.0/Toprie/Toprie/Setting.cs
@@ -4101,13 +4101,13 @@ namespace JoyD.Windows.CS
// 写入CSV文件头部(使用中文标题)
writer.WriteLine("索引,X坐标,Y坐标,宽度,高度,颜色");
- // 遍历所有测温区,将信息写入CSV文件
- foreach (RegionInfo region in _drawnRectangles)
+ // 遍历所有原始测温区,将相对坐标信息写入CSV文件
+ foreach (RegionInfo region in _originalTemperatureZones)
{
// 获取颜色的十六进制表示
string colorHex = ColorTranslator.ToHtml(region.Color);
- // 写入一行数据,格式:索引,X坐标,Y坐标,宽度,高度,颜色
+ // 写入一行数据,格式:索引,X坐标,Y坐标,宽度,高度,颜色(相对坐标)
writer.WriteLine($"{region.Index},{region.ImageRectangle.X},{region.ImageRectangle.Y},{region.ImageRectangle.Width},{region.ImageRectangle.Height},{colorHex}");
}
}
@@ -4185,11 +4185,212 @@ namespace JoyD.Windows.CS
///
/// 窗口关闭时停止定时器并释放资源
///
+ ///
+ /// 检查所有测温区是否在检测区内
+ ///
+ /// 所有测温区都在检测区内返回true,否则返回false
+ private bool CheckTemperatureZonesInDetectionZone()
+ {
+ // 创建检测区矩形
+ Rectangle detectionRect = new Rectangle(
+ _detectionZone.X,
+ _detectionZone.Y,
+ _detectionZone.Width,
+ _detectionZone.Height
+ );
+
+ // 遍历所有测温区
+ foreach (RegionInfo region in _drawnRectangles)
+ {
+ // 检查测温区是否完全包含在检测区内
+ if (!detectionRect.Contains(region.ImageRectangle))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ ///
+ /// 检查温差图是否在检测区内
+ ///
+ /// 温差图完全在检测区内返回true,否则返回false
+ private bool CheckTempDiffInDetectionZone()
+ {
+ // 如果没有温差图,直接返回true
+ if (_tempDiffOverlayImage == null || !(_tempDiffOverlayImage is Bitmap))
+ {
+ return true;
+ }
+
+ Bitmap bitmap = (Bitmap)_tempDiffOverlayImage;
+ // 创建检测区矩形
+ Rectangle detectionRect = new Rectangle(
+ _detectionZone.X,
+ _detectionZone.Y,
+ _detectionZone.Width,
+ _detectionZone.Height
+ );
+
+ // 检查温差图中是否有超出检测区的像素
+ for (int y = 0; y < bitmap.Height; y++)
+ {
+ for (int x = 0; x < bitmap.Width; x++)
+ {
+ Color pixelColor = bitmap.GetPixel(x, y);
+ if (pixelColor.A > 0) // 只检查非透明像素
+ {
+ Point pixelPoint = new Point(x, y);
+ if (!detectionRect.Contains(pixelPoint))
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ ///
+ /// 裁切测温区到检测区内
+ ///
+ private void CropTemperatureZonesToDetectionZone()
+ {
+ // 创建检测区矩形
+ Rectangle detectionRect = new Rectangle(
+ _detectionZone.X,
+ _detectionZone.Y,
+ _detectionZone.Width,
+ _detectionZone.Height
+ );
+
+ // 遍历所有测温区
+ for (int i = _drawnRectangles.Count - 1; i >= 0; i--)
+ {
+ RegionInfo region = _drawnRectangles[i];
+
+ // 如果测温区完全在检测区内,跳过
+ if (detectionRect.Contains(region.ImageRectangle))
+ {
+ continue;
+ }
+
+ // 计算两个矩形的交集,确保结果完全在检测区内
+ Rectangle newRect = Rectangle.Intersect(region.ImageRectangle, detectionRect);
+
+ // 如果裁切后矩形仍然有大小(最小2x2像素),更新测温区
+ if (newRect.Width > 2 && newRect.Height > 2)
+ {
+ region.ImageRectangle = newRect;
+ }
+ else
+ {
+ // 如果裁切后矩形太小,移除该测温区
+ _drawnRectangles.RemoveAt(i);
+ }
+ }
+
+ // 同步列表
+ SyncTemperatureZonesFromDrawnRectangles();
+
+ // 更新叠加层
+ CreateRectangleOverlayImage();
+ }
+
+ ///
+ /// 裁切温差图到检测区内
+ ///
+ private void CropTempDiffToDetectionZone()
+ {
+ // 如果没有温差图,直接返回
+ if (_tempDiffOverlayImage == null || !(_tempDiffOverlayImage is Bitmap))
+ {
+ return;
+ }
+
+ Bitmap bitmap = (Bitmap)_tempDiffOverlayImage;
+ // 创建检测区矩形
+ Rectangle detectionRect = new Rectangle(
+ _detectionZone.X,
+ _detectionZone.Y,
+ _detectionZone.Width,
+ _detectionZone.Height
+ );
+
+ // 创建新的位图用于保存裁切后的温差图
+ Bitmap croppedBitmap = new Bitmap(bitmap.Width, bitmap.Height);
+
+ // 将超出检测区的像素设置为透明
+ for (int y = 0; y < bitmap.Height; y++)
+ {
+ for (int x = 0; x < bitmap.Width; x++)
+ {
+ Color pixelColor = bitmap.GetPixel(x, y);
+ if (pixelColor.A > 0) // 只处理非透明像素
+ {
+ Point pixelPoint = new Point(x, y);
+ if (!detectionRect.Contains(pixelPoint))
+ {
+ // 设置为透明
+ croppedBitmap.SetPixel(x, y, Color.Transparent);
+ }
+ else
+ {
+ // 保留原颜色
+ croppedBitmap.SetPixel(x, y, pixelColor);
+ }
+ }
+ }
+ }
+
+ // 释放旧的温差图并替换为裁切后的
+ _tempDiffOverlayImage.Dispose();
+ _tempDiffOverlayImage = croppedBitmap;
+ }
+
private void Setting_FormClosing(object sender, FormClosingEventArgs e)
{
// 当自动配置为true时,保存回加载时的文件
if (_autoConfig && !string.IsNullOrEmpty(_projectPath))
{
+ bool hasOutOfBounds = false;
+ string message = "";
+
+ // 检查测温区
+ if (!CheckTemperatureZonesInDetectionZone())
+ {
+ hasOutOfBounds = true;
+ message += "部分测温区超出检测区范围,";
+ }
+
+ // 检查温差图
+ if (!CheckTempDiffInDetectionZone())
+ {
+ hasOutOfBounds = true;
+ message += "部分温差图超出检测区范围,";
+ }
+
+ // 如果有超出部分,提示用户
+ if (hasOutOfBounds)
+ {
+ message += "是否自动裁切并保存?";
+ DialogResult result = MessageBox.Show(message, "保存确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
+
+ if (result == DialogResult.Cancel)
+ {
+ e.Cancel = true; // 取消关闭窗口
+ return;
+ }
+ else
+ {
+ // 裁切超出部分
+ CropTemperatureZonesToDetectionZone();
+ CropTempDiffToDetectionZone();
+ }
+ }
+
// 自动保存测温区配置
SaveTempRegionToDefaultPath();
// 自动保存温差图配置
@@ -5367,8 +5568,8 @@ namespace JoyD.Windows.CS
writer.WriteLine("像素温度数据");
writer.WriteLine("X坐标,Y坐标,温度值(°C)");
- // 从_tempDiffOverlayImage中获取真实温度数据
- if (_tempDiffOverlayImage != null && _tempDiffOverlayImage is Bitmap)
+ // 使用原始温差图数据(相对坐标)保存
+ if (_originalTempDiffData.Count > 0)
{
Bitmap bitmap = (Bitmap)_tempDiffOverlayImage;
@@ -5480,59 +5681,15 @@ namespace JoyD.Windows.CS
writer.WriteLine("像素温度数据");
writer.WriteLine("X坐标,Y坐标,温度值(°C)");
- // 从_tempDiffOverlayImage中获取真实温度数据
- if (_tempDiffOverlayImage != null && _tempDiffOverlayImage is Bitmap)
+ // 使用_originalTempDiffData保存相对坐标的温差数据
+ if (_originalTempDiffData.Count > 0)
{
- Bitmap bitmap = (Bitmap)_tempDiffOverlayImage;
-
- // 锁定位图以提高性能
- BitmapData bitmapData = bitmap.LockBits(
- new Rectangle(0, 0, bitmap.Width, bitmap.Height),
- ImageLockMode.ReadOnly,
- PixelFormat.Format32bppArgb);
-
- try
+ // 遍历原始温差数据字典,保存相对坐标的温差数据
+ foreach (KeyValuePair pair in _originalTempDiffData)
{
- int bytesPerPixel = 4; // 32bppArgb格式每像素4字节
- int byteCount = bitmapData.Stride * bitmapData.Height;
- byte[] pixels = new byte[byteCount];
-
- // 将图像数据复制到数组
- Marshal.Copy(bitmapData.Scan0, pixels, 0, byteCount);
-
- // 保存所有非透明像素
- for (int y = 0; y < bitmap.Height; y++)
- {
- for (int x = 0; x < bitmap.Width; x++)
- {
- // 计算当前像素在数组中的位置
- 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);
+ Point relativePoint = pair.Key;
+ double temperature = pair.Value;
+ writer.WriteLine($"{relativePoint.X},{relativePoint.Y},{temperature:F1}");
}
}
else