更新区域绘制逻辑和优化增量绘制

This commit is contained in:
zqm
2025-11-06 17:04:37 +08:00
parent 31e9f6a6eb
commit 467e8fbb7d

View File

@@ -29,6 +29,8 @@ namespace JoyD.Windows.CS
private List<RegionInfo> _drawnRectangles = new List<RegionInfo>();
private Color _selectedColor = Color.Red;
private int _regionCounter = 0;
// 叠加层图像 - 用于存储已完成绘制的矩形
private Image _rectangleOverlayImage = null;
public Setting()
{
@@ -124,7 +126,92 @@ namespace JoyD.Windows.CS
}
/// <summary>
/// 鼠标释放事件 - 完成矩形绘制
/// 创建或更新叠加层图像(完全重绘)
/// 仅在必要时调用,如图像尺寸改变或需要完全重绘
/// </summary>
private void CreateRectangleOverlayImage()
{
// 如果PictureBox没有图像或者尺寸为0则不创建叠加层
if (picBoxTemp.Image == null || picBoxTemp.Image.Width == 0 || picBoxTemp.Image.Height == 0)
{
return;
}
// 如果叠加层图像不存在或尺寸不匹配,创建新的
if (_rectangleOverlayImage == null ||
_rectangleOverlayImage.Width != picBoxTemp.Image.Width ||
_rectangleOverlayImage.Height != picBoxTemp.Image.Height)
{
// 释放旧的叠加层图像资源
if (_rectangleOverlayImage != null)
{
_rectangleOverlayImage.Dispose();
}
// 创建新的叠加层图像
_rectangleOverlayImage = new Bitmap(picBoxTemp.Image.Width, picBoxTemp.Image.Height);
// 清除背景为透明
using (Graphics g = Graphics.FromImage(_rectangleOverlayImage))
{
g.Clear(Color.Transparent);
}
// 由于创建了新图像,需要重新绘制所有矩形
foreach (RegionInfo region in _drawnRectangles)
{
DrawRegionToOverlay(region);
}
}
else
{
// 清除现有叠加层图像
using (Graphics g = Graphics.FromImage(_rectangleOverlayImage))
{
g.Clear(Color.Transparent);
}
// 重绘所有矩形
foreach (RegionInfo region in _drawnRectangles)
{
DrawRegionToOverlay(region);
}
}
}
/// <summary>
/// 将单个区域绘制到叠加层图像
/// 用于增量绘制,避免每次都重绘所有矩形
/// </summary>
/// <param name="region">要绘制的区域信息</param>
private void DrawRegionToOverlay(RegionInfo region)
{
if (_rectangleOverlayImage == null)
return;
using (Graphics g = Graphics.FromImage(_rectangleOverlayImage))
{
// 使用每个区域自己的颜色绘制矩形
g.DrawRectangle(new Pen(region.Color, 2), region.Rectangle);
// 绘制区域序号
using (Font font = new Font("Arial", 12, FontStyle.Bold))
using (SolidBrush brush = new SolidBrush(region.Color))
{
// 在矩形左上角绘制序号
Point textPosition = new Point(region.Rectangle.X + 5, region.Rectangle.Y - 15);
// 确保文本不超出控件边界
if (textPosition.Y < 0)
textPosition.Y = 5;
g.DrawString(region.Index.ToString(), font, brush, textPosition);
}
}
}
/// <summary>
/// 鼠标释放事件 - 完成矩形绘制(优化版)
/// 使用增量绘制,避免每次都重绘所有矩形
/// </summary>
private void PicBoxTemp_MouseUp(object sender, MouseEventArgs e)
{
@@ -145,7 +232,29 @@ namespace JoyD.Windows.CS
};
_drawnRectangles.Add(regionInfo);
// 可以在这里添加处理矩形区域的逻辑,如保存区域信息等
// 检查是否需要完全重建叠加层
bool needFullRebuild = false;
// 如果叠加层不存在或尺寸不匹配,需要完全重建
if (_rectangleOverlayImage == null ||
(picBoxTemp.Image != null && (
_rectangleOverlayImage.Width != picBoxTemp.Image.Width ||
_rectangleOverlayImage.Height != picBoxTemp.Image.Height)))
{
needFullRebuild = true;
}
if (needFullRebuild)
{
// 完全重建叠加层
CreateRectangleOverlayImage();
}
else
{
// 仅绘制新添加的矩形(增量绘制)
DrawRegionToOverlay(regionInfo);
}
// 显示绘制完成的提示
ToolStripStatusLabel statusLabel = new ToolStripStatusLabel
@@ -163,31 +272,17 @@ namespace JoyD.Windows.CS
}
/// <summary>
/// 绘制事件 - 显示矩形框
/// 绘制事件 - 显示矩形框(实现图像合并机制)
/// </summary>
private void PicBoxTemp_Paint(object sender, PaintEventArgs e)
{
// 绘制所有已完成的矩形
foreach (RegionInfo region in _drawnRectangles)
// 图像合并机制:先绘制叠加层
if (_rectangleOverlayImage != null)
{
// 使用每个区域自己的颜色绘制矩形
e.Graphics.DrawRectangle(new Pen(region.Color, 2), region.Rectangle);
// 绘制区域序号
using (Font font = new Font("Arial", 12, FontStyle.Bold))
using (SolidBrush brush = new SolidBrush(region.Color))
{
// 在矩形左上角绘制序号
Point textPosition = new Point(region.Rectangle.X + 5, region.Rectangle.Y - 15);
// 确保文本不超出控件边界
if (textPosition.Y < 0)
textPosition.Y = 5;
e.Graphics.DrawString(region.Index.ToString(), font, brush, textPosition);
}
e.Graphics.DrawImage(_rectangleOverlayImage, Point.Empty);
}
// 绘制当前正在绘制的矩形
// 绘制临时矩形(当前正在绘制的矩形
if (!_currentRectangle.IsEmpty)
{
using (Pen dashedPen = new Pen(Color.Blue, 2))
@@ -322,11 +417,18 @@ namespace JoyD.Windows.CS
}
/// <summary>
/// 窗口关闭时停止定时器
/// 窗口关闭时停止定时器并释放资源
/// </summary>
private void Setting_FormClosing(object sender, FormClosingEventArgs e)
{
_timer.Stop();
// 释放叠加层图像资源
if (_rectangleOverlayImage != null)
{
_rectangleOverlayImage.Dispose();
_rectangleOverlayImage = null;
}
}
/// <summary>
@@ -367,6 +469,7 @@ namespace JoyD.Windows.CS
/// <summary>
/// 更新pictureBoxTemperatureDisplay的图像
/// 此方法可以从任何线程调用
/// 注意:根据要求,不修改此方法的核心逻辑
/// </summary>
/// <param name="NewImage">要显示的新图像</param>
public void UpdateRealTimeImage(Image NewImage)