修复温差层退出后叠加层光标不可见问题,优化光标资源管理

This commit is contained in:
zqm
2025-11-10 15:51:46 +08:00
parent 145679cdd5
commit 48e50f2b70

View File

@@ -34,6 +34,8 @@ namespace JoyD.Windows.CS
private int _regionCounter = 0; private int _regionCounter = 0;
// 叠加层图像 - 用于存储已完成绘制的矩形 // 叠加层图像 - 用于存储已完成绘制的矩形
private Image _rectangleOverlayImage = null; private Image _rectangleOverlayImage = null;
// 温差层图像 - 用于存储温差图绘制内容
private Image _tempDiffOverlayImage = null;
private int _hoveredRegionIndex = -1; // 当前悬停的区域索引(-1表示没有悬停在任何区域上 private int _hoveredRegionIndex = -1; // 当前悬停的区域索引(-1表示没有悬停在任何区域上
// 当前选中的区域索引 // 当前选中的区域索引
private int _selectedRegionIndex = -1; private int _selectedRegionIndex = -1;
@@ -51,6 +53,8 @@ namespace JoyD.Windows.CS
// 画笔大小相关变量 // 画笔大小相关变量
private int _currentBrushSize = 1; // 默认画笔大小为1像素 private int _currentBrushSize = 1; // 默认画笔大小为1像素
// 温差图绘制相关变量
private Point _lastDrawPoint = Point.Empty; // 上一个绘制点的位置
public Setting() public Setting()
{ {
@@ -617,6 +621,8 @@ namespace JoyD.Windows.CS
// 刷新绘制 // 刷新绘制
picBoxTemp.Invalidate(); picBoxTemp.Invalidate();
} }
// 处理选中区域的调整大小或移动 // 处理选中区域的调整大小或移动
else if (e.Button == MouseButtons.Left && !_isDrawingMode && _selectedRegionIndex != -1) else if (e.Button == MouseButtons.Left && !_isDrawingMode && _selectedRegionIndex != -1)
@@ -861,15 +867,35 @@ namespace JoyD.Windows.CS
/// </summary> /// </summary>
private void ExitTempDiffDrawingMode() private void ExitTempDiffDrawingMode()
{ {
// 重置上一个绘制点
_lastDrawPoint = Point.Empty;
_isTempDiffDrawingMode = false; _isTempDiffDrawingMode = false;
btnDrawTempDiff.Checked = false; btnDrawTempDiff.Checked = false;
// 重置鼠标光标并释放自定义光标资源 // 重置鼠标光标并安全释放自定义光标资源
if (picBoxTemp.Cursor != Cursors.Default) try
{ {
Cursor oldCursor = picBoxTemp.Cursor; Cursor currentCursor = picBoxTemp.Cursor;
// 只释放自定义光标,不释放系统光标
if (currentCursor != null && currentCursor != Cursors.Default &&
currentCursor != Cursors.Cross && currentCursor != Cursors.Hand &&
currentCursor != Cursors.IBeam && currentCursor != Cursors.WaitCursor)
{
// 先设置新光标,再释放旧光标
picBoxTemp.Cursor = Cursors.Default;
currentCursor.Dispose();
}
else if (currentCursor != Cursors.Default)
{
// 如果是系统光标,直接设置为默认光标
picBoxTemp.Cursor = Cursors.Default;
}
}
catch (Exception ex)
{
Console.WriteLine("重置光标资源时发生异常: " + ex.Message);
// 确保光标设置为默认值
picBoxTemp.Cursor = Cursors.Default; picBoxTemp.Cursor = Cursors.Default;
oldCursor.Dispose(); // 释放自定义光标资源
} }
// 更新按钮提示文本 // 更新按钮提示文本
@@ -1126,22 +1152,94 @@ namespace JoyD.Windows.CS
selectedColor = (Color)tempDiffData[selectedRowIndex]["color"]; selectedColor = (Color)tempDiffData[selectedRowIndex]["color"];
} }
// 创建并设置自定义光标 try
Cursor customCursor = CreateCustomBrushCursor(_currentBrushSize, selectedColor);
// 确保不重复设置相同的光标(避免资源泄漏)
if (picBoxTemp.Cursor != customCursor)
{ {
// 释放旧光标资源 // 创建并设置自定义光标
picBoxTemp.Cursor.Dispose(); Cursor customCursor = CreateCustomBrushCursor(_currentBrushSize, selectedColor);
picBoxTemp.Cursor = customCursor;
// 确保不重复设置相同的光标(避免资源泄漏)
if (picBoxTemp.Cursor != customCursor)
{
// 获取旧光标
Cursor oldCursor = picBoxTemp.Cursor;
// 先设置新光标
picBoxTemp.Cursor = customCursor;
// 只释放自定义光标,不释放系统光标
if (oldCursor != null && oldCursor != Cursors.Default &&
oldCursor != Cursors.Cross && oldCursor != Cursors.Hand &&
oldCursor != Cursors.IBeam && oldCursor != Cursors.WaitCursor)
{
oldCursor.Dispose();
}
}
}
catch (Exception ex)
{
Console.WriteLine("设置自定义光标时发生异常: " + ex.Message);
// 出现异常时设置为十字光标
try
{
if (picBoxTemp.Cursor != Cursors.Cross)
{
picBoxTemp.Cursor = Cursors.Cross;
}
}
catch {}
} }
// 如果按下鼠标左键,执行绘制操作(这里可能需要根据实际绘制逻辑补充) // 如果按下鼠标左键,执行绘制操作
if (e.Button == MouseButtons.Left) if (e.Button == MouseButtons.Left && picBoxTemp.Image != null)
{ {
// 这里可以添加实际的绘制逻辑 // 初始化温差层图像(如果不存在或尺寸不匹配)
// 目前仅设置光标,具体绘制代码可能在其他事件中 if (_tempDiffOverlayImage == null ||
_tempDiffOverlayImage.Width != picBoxTemp.Image.Width ||
_tempDiffOverlayImage.Height != picBoxTemp.Image.Height)
{
InitializeTempDiffOverlayImage();
}
// 获取相对于图像的坐标
Point imagePoint = ControlPointToImagePoint(e.Location);
// 在温差层图像上绘制
using (Graphics g = Graphics.FromImage(_tempDiffOverlayImage))
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
// 使用当前选中的颜色和画笔大小绘制
using (Pen pen = new Pen(selectedColor, _currentBrushSize))
{
pen.StartCap = LineCap.Round;
pen.EndCap = LineCap.Round;
pen.LineJoin = LineJoin.Round;
// 如果是首次绘制或上一个点无效,记录当前点作为起点
if (_lastDrawPoint == Point.Empty)
{
_lastDrawPoint = imagePoint;
// 绘制起始点的圆形
int radius = _currentBrushSize / 2;
g.FillEllipse(new SolidBrush(selectedColor),
imagePoint.X - radius,
imagePoint.Y - radius,
_currentBrushSize,
_currentBrushSize);
}
else
{
// 绘制连线
g.DrawLine(pen, _lastDrawPoint, imagePoint);
// 更新上一个点
_lastDrawPoint = imagePoint;
}
}
}
// 触发重绘
picBoxTemp.Invalidate();
} }
return; // 温差图绘制模式下,不执行其他鼠标移动逻辑 return; // 温差图绘制模式下,不执行其他鼠标移动逻辑
@@ -1354,6 +1452,32 @@ namespace JoyD.Windows.CS
} }
} }
/// <summary>
/// 初始化温差层图像
/// 创建与原图大小相同的透明图像用于温差绘制
/// </summary>
private void InitializeTempDiffOverlayImage()
{
if (picBoxTemp.Image == null || picBoxTemp.Image.Width == 0 || picBoxTemp.Image.Height == 0)
return;
// 释放旧的温差层图像资源
if (_tempDiffOverlayImage != null)
{
_tempDiffOverlayImage.Dispose();
_tempDiffOverlayImage = null;
}
// 创建新的温差层图像
_tempDiffOverlayImage = new Bitmap(picBoxTemp.Image.Width, picBoxTemp.Image.Height);
// 清除背景为透明
using (Graphics g = Graphics.FromImage(_tempDiffOverlayImage))
{
g.Clear(Color.Transparent);
}
}
/// <summary> /// <summary>
/// 将单个区域绘制到叠加层图像 /// 将单个区域绘制到叠加层图像
/// 用于增量绘制,避免每次都重绘所有矩形 /// 用于增量绘制,避免每次都重绘所有矩形
@@ -1370,8 +1494,8 @@ namespace JoyD.Windows.CS
// 设置高质量绘图 // 设置高质量绘图
g.SmoothingMode = SmoothingMode.AntiAlias; g.SmoothingMode = SmoothingMode.AntiAlias;
// 使用每个区域自己的颜色和当前选择的画笔大小绘制矩形 // 使用每个区域自己的颜色和固定线条粗细绘制矩形
g.DrawRectangle(new Pen(region.Color, _currentBrushSize), region.ImageRectangle); g.DrawRectangle(new Pen(region.Color, 2), region.ImageRectangle);
// 绘制区域序号 // 绘制区域序号
using (Font font = new Font("Arial", 12, FontStyle.Bold)) using (Font font = new Font("Arial", 12, FontStyle.Bold))
@@ -1395,6 +1519,12 @@ namespace JoyD.Windows.CS
/// </summary> /// </summary>
private void PicBoxTemp_MouseUp(object sender, MouseEventArgs e) private void PicBoxTemp_MouseUp(object sender, MouseEventArgs e)
{ {
// 在温差图绘制模式下,松开鼠标时重置上一个绘制点
if (_isTempDiffDrawingMode)
{
_lastDrawPoint = Point.Empty;
}
// 结束调整大小 // 结束调整大小
if (_isResizing && e.Button == MouseButtons.Left) if (_isResizing && e.Button == MouseButtons.Left)
{ {
@@ -1491,7 +1621,17 @@ namespace JoyD.Windows.CS
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
// 图像合并机制:先绘制叠加层(根据控件尺寸进行缩放) // 图像合并机制:
// 1. 先绘制温差层(根据控件尺寸进行缩放)
if (_tempDiffOverlayImage != null && picBoxTemp.Image != null)
{
// 计算缩放后的目标矩形
Rectangle destRect = new Rectangle(0, 0, picBoxTemp.ClientSize.Width, picBoxTemp.ClientSize.Height);
// 绘制缩放后的温差层
e.Graphics.DrawImage(_tempDiffOverlayImage, destRect, 0, 0, _tempDiffOverlayImage.Width, _tempDiffOverlayImage.Height, GraphicsUnit.Pixel);
}
// 2. 然后绘制叠加层(根据控件尺寸进行缩放)
if (_rectangleOverlayImage != null && picBoxTemp.Image != null) if (_rectangleOverlayImage != null && picBoxTemp.Image != null)
{ {
// 计算缩放后的目标矩形 // 计算缩放后的目标矩形
@@ -1847,6 +1987,13 @@ namespace JoyD.Windows.CS
_rectangleOverlayImage.Dispose(); _rectangleOverlayImage.Dispose();
_rectangleOverlayImage = null; _rectangleOverlayImage = null;
} }
// 释放温差层图像资源
if (_tempDiffOverlayImage != null)
{
_tempDiffOverlayImage.Dispose();
_tempDiffOverlayImage = null;
}
} }
/// <summary> /// <summary>
@@ -2116,6 +2263,15 @@ namespace JoyD.Windows.CS
/// </summary> /// </summary>
private void UpdateOverlayForSizeChange() private void UpdateOverlayForSizeChange()
{ {
// 处理温差层图像尺寸变化
if (picBoxTemp.Image != null && _tempDiffOverlayImage != null && (
_tempDiffOverlayImage.Width != picBoxTemp.Image.Width ||
_tempDiffOverlayImage.Height != picBoxTemp.Image.Height))
{
InitializeTempDiffOverlayImage();
}
// 处理矩形叠加层图像
if (picBoxTemp.Image != null && _drawnRectangles.Count > 0) if (picBoxTemp.Image != null && _drawnRectangles.Count > 0)
{ {
CreateRectangleOverlayImage(); CreateRectangleOverlayImage();