保存时自动裁切
This commit is contained in:
@@ -4101,13 +4101,13 @@ namespace JoyD.Windows.CS
|
|||||||
// 写入CSV文件头部(使用中文标题)
|
// 写入CSV文件头部(使用中文标题)
|
||||||
writer.WriteLine("索引,X坐标,Y坐标,宽度,高度,颜色");
|
writer.WriteLine("索引,X坐标,Y坐标,宽度,高度,颜色");
|
||||||
|
|
||||||
// 遍历所有测温区,将信息写入CSV文件
|
// 遍历所有原始测温区,将相对坐标信息写入CSV文件
|
||||||
foreach (RegionInfo region in _drawnRectangles)
|
foreach (RegionInfo region in _originalTemperatureZones)
|
||||||
{
|
{
|
||||||
// 获取颜色的十六进制表示
|
// 获取颜色的十六进制表示
|
||||||
string colorHex = ColorTranslator.ToHtml(region.Color);
|
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}");
|
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
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 窗口关闭时停止定时器并释放资源
|
/// 窗口关闭时停止定时器并释放资源
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <summary>
|
||||||
|
/// 检查所有测温区是否在检测区内
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>所有测温区都在检测区内返回true,否则返回false</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查温差图是否在检测区内
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>温差图完全在检测区内返回true,否则返回false</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 裁切测温区到检测区内
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 裁切温差图到检测区内
|
||||||
|
/// </summary>
|
||||||
|
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)
|
private void Setting_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
{
|
{
|
||||||
// 当自动配置为true时,保存回加载时的文件
|
// 当自动配置为true时,保存回加载时的文件
|
||||||
if (_autoConfig && !string.IsNullOrEmpty(_projectPath))
|
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();
|
SaveTempRegionToDefaultPath();
|
||||||
// 自动保存温差图配置
|
// 自动保存温差图配置
|
||||||
@@ -5367,8 +5568,8 @@ namespace JoyD.Windows.CS
|
|||||||
writer.WriteLine("像素温度数据");
|
writer.WriteLine("像素温度数据");
|
||||||
writer.WriteLine("X坐标,Y坐标,温度值(°C)");
|
writer.WriteLine("X坐标,Y坐标,温度值(°C)");
|
||||||
|
|
||||||
// 从_tempDiffOverlayImage中获取真实温度数据
|
// 使用原始温差图数据(相对坐标)保存
|
||||||
if (_tempDiffOverlayImage != null && _tempDiffOverlayImage is Bitmap)
|
if (_originalTempDiffData.Count > 0)
|
||||||
{
|
{
|
||||||
Bitmap bitmap = (Bitmap)_tempDiffOverlayImage;
|
Bitmap bitmap = (Bitmap)_tempDiffOverlayImage;
|
||||||
|
|
||||||
@@ -5480,59 +5681,15 @@ namespace JoyD.Windows.CS
|
|||||||
writer.WriteLine("像素温度数据");
|
writer.WriteLine("像素温度数据");
|
||||||
writer.WriteLine("X坐标,Y坐标,温度值(°C)");
|
writer.WriteLine("X坐标,Y坐标,温度值(°C)");
|
||||||
|
|
||||||
// 从_tempDiffOverlayImage中获取真实温度数据
|
// 使用_originalTempDiffData保存相对坐标的温差数据
|
||||||
if (_tempDiffOverlayImage != null && _tempDiffOverlayImage is Bitmap)
|
if (_originalTempDiffData.Count > 0)
|
||||||
{
|
{
|
||||||
Bitmap bitmap = (Bitmap)_tempDiffOverlayImage;
|
// 遍历原始温差数据字典,保存相对坐标的温差数据
|
||||||
|
foreach (KeyValuePair<Point, double> pair in _originalTempDiffData)
|
||||||
// 锁定位图以提高性能
|
|
||||||
BitmapData bitmapData = bitmap.LockBits(
|
|
||||||
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
|
|
||||||
ImageLockMode.ReadOnly,
|
|
||||||
PixelFormat.Format32bppArgb);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
int bytesPerPixel = 4; // 32bppArgb格式每像素4字节
|
Point relativePoint = pair.Key;
|
||||||
int byteCount = bitmapData.Stride * bitmapData.Height;
|
double temperature = pair.Value;
|
||||||
byte[] pixels = new byte[byteCount];
|
writer.WriteLine($"{relativePoint.X},{relativePoint.Y},{temperature:F1}");
|
||||||
|
|
||||||
// 将图像数据复制到数组
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user