将擦除模式按钮移到btnDrawTempDiff后面,并优化温差图绘制模式的矩形填充颜色

This commit is contained in:
zqm
2025-11-11 09:23:45 +08:00
parent 9c86cc2e5f
commit a6f2acd08a
2 changed files with 107 additions and 120 deletions

View File

@@ -146,6 +146,7 @@ namespace JoyD.Windows.CS
this.btnSelectColor,
this.btnDeleteRegion,
this.btnDrawTempDiff,
this.btnEraseTempDiff,
this.btnAddTempDiff,
this.btnDeleteTempDiff,
new System.Windows.Forms.ToolStripSeparator(),
@@ -154,8 +155,7 @@ namespace JoyD.Windows.CS
this.btnBrushSize5,
this.btnBrushSize10,
this.btnBrushSize15,
this.btnBrushSize25,
this.btnEraseTempDiff});
this.btnBrushSize25});
this.toolStrip.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.Flow;
this.toolStrip.Location = new System.Drawing.Point(3, 0);
this.toolStrip.MaximumSize = new System.Drawing.Size(0, 100);

View File

@@ -58,6 +58,7 @@ namespace JoyD.Windows.CS
private bool _isDrawingRectangle = false; // 是否正在绘制矩形
private Point _rectangleStartPoint = Point.Empty; // 矩形起始点
private bool _isEraseMode = false; // 擦除模式标志
private Rectangle _tempDiffTempRectangle = Rectangle.Empty; // 临时温差图矩形预览
public Setting()
{
@@ -1326,87 +1327,10 @@ namespace JoyD.Windows.CS
int width = rectBottomRight.X - rectTopLeft.X;
int height = rectBottomRight.Y - rectTopLeft.Y;
Rectangle rect = new Rectangle(x, y, width, height);
// 存储临时矩形用于在Paint事件中绘制预览
_tempDiffTempRectangle = new Rectangle(x, y, width, height);
// 对于擦除模式,在临时层上绘制预览框,不影响实际的温差图
if (_isEraseMode)
{
// 创建临时缓冲区用于绘制预览
Bitmap bufferBitmap = null;
try
{
bufferBitmap = new Bitmap(picBoxTemp.Width, picBoxTemp.Height);
using (Graphics g = Graphics.FromImage(bufferBitmap))
{
// 绘制背景图像
if (picBoxTemp.Image != null)
{
g.DrawImage(picBoxTemp.Image, 0, 0, picBoxTemp.Width, picBoxTemp.Height);
}
// 绘制温差层
if (_tempDiffOverlayImage != null)
{
g.DrawImage(_tempDiffOverlayImage, 0, 0, picBoxTemp.Width, picBoxTemp.Height);
}
// 绘制虚线预览框
using (Pen dashPen = new Pen(Color.White, 1))
{
dashPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
// 将图像坐标转换为控件坐标
Rectangle controlRect = ImageRectangleToControlRectangle(rect);
g.DrawRectangle(dashPen, controlRect);
}
}
// 直接在控件上绘制缓冲区内容
using (Graphics g = picBoxTemp.CreateGraphics())
{
g.DrawImage(bufferBitmap, 0, 0);
}
// 防止闪烁
return;
}
finally
{
if (bufferBitmap != null)
bufferBitmap.Dispose();
}
}
else
{
// 普通绘制模式:使用半透明填充和边框
using (Bitmap tempBitmap = new Bitmap(_tempDiffOverlayImage))
{
using (Graphics g = Graphics.FromImage(tempBitmap))
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
// 创建半透明的填充颜色
Color fillColor = Color.FromArgb(128, selectedColor);
// 绘制填充矩形
g.FillRectangle(new SolidBrush(fillColor), rect);
// 绘制矩形边框线径固定为1以更精确控制绘制逻辑
using (Pen pen = new Pen(selectedColor, 1))
{
g.DrawRectangle(pen, rect);
}
}
// 将临时位图复制回温差层图像
using (Graphics g = Graphics.FromImage(_tempDiffOverlayImage))
{
g.DrawImage(tempBitmap, 0, 0);
}
}
}
// 触发重绘
// 触发重绘让Paint事件绘制临时矩形
picBoxTemp.Invalidate();
}
// 普通绘制/擦除操作未按住Ctrl键
@@ -1776,58 +1700,70 @@ namespace JoyD.Windows.CS
/// </summary>
private void PicBoxTemp_MouseUp(object sender, MouseEventArgs e)
{
// 温差图绘制/擦除模式下,松开鼠标时重置绘制状态
// 温差图绘制模式下的矩形绘制结束
if (_isTempDiffDrawingMode || _isEraseMode)
{
_lastDrawPoint = Point.Empty;
// 结束矩形绘制/擦除
// 结束矩形绘制/擦除Ctrl+鼠标绘制模式)
if (_isDrawingRectangle && picBoxTemp.Image != null)
{
// 如果是擦除模式在MouseUp时一次性擦除矩形区域
if (_isEraseMode)
{
// 获取相对于图像的当前坐标
Point currentImagePoint = ControlPointToImagePoint(e.Location);
// 计算矩形参数:左上点是起笔方块的左上点,右下点是当前鼠标位置+画笔一半的宽高(基于光标大小)
// 使用反向缩放比例:将控件坐标中的光标大小转换为图像坐标
float scaleX = (float)picBoxTemp.Image.Width / picBoxTemp.ClientSize.Width;
float scaleY = (float)picBoxTemp.Image.Height / picBoxTemp.ClientSize.Height;
float scaledHalfBrushSizeX = _currentBrushSize / 2 * scaleX;
float scaledHalfBrushSizeY = _currentBrushSize / 2 * scaleY;
// 计算起始点和结束点
Point startPoint = new Point(
(int)(_rectangleStartPoint.X),
(int)(_rectangleStartPoint.Y)
);
Point endPoint = new Point(
(int)(currentImagePoint.X + scaledHalfBrushSizeX),
(int)(currentImagePoint.Y + scaledHalfBrushSizeY)
);
// 无论绘制方向如何,都确保左上角为起始点
int x = Math.Min(startPoint.X, endPoint.X);
int y = Math.Min(startPoint.Y, endPoint.Y);
int width = Math.Abs(endPoint.X - startPoint.X);
int height = Math.Abs(endPoint.Y - startPoint.Y);
Rectangle rect = new Rectangle(x, y, width, height);
// 只有当矩形有实际大小时才执行擦除
if (width > 0 && height > 0)
// 使用临时矩形进行绘制或擦除操作
if (!_tempDiffTempRectangle.IsEmpty && _tempDiffTempRectangle.Width > 0 && _tempDiffTempRectangle.Height > 0)
{
using (Graphics g = Graphics.FromImage(_tempDiffOverlayImage))
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
if (_isEraseMode)
{
// 擦除模式使用透明色填充设置CompositingMode为清除
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
g.FillRectangle(Brushes.Transparent, rect);
g.FillRectangle(Brushes.Transparent, _tempDiffTempRectangle);
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
}
else
{
// 获取当前选中的温差图例颜色
Color selectedColor = Color.Black; // 默认颜色
int selectedRowIndex = -1;
// 尝试获取选中行的颜色
if (dataGridViewTempDiff.SelectedRows.Count > 0)
{
selectedRowIndex = dataGridViewTempDiff.SelectedRows[0].Index;
}
else if (dataGridViewTempDiff.SelectedCells.Count > 0)
{
selectedRowIndex = dataGridViewTempDiff.SelectedCells[0].RowIndex;
}
// 如果选中行索引有效,获取对应的颜色
if (selectedRowIndex >= 0 && selectedRowIndex < tempDiffData.Count)
{
selectedColor = (Color)tempDiffData[selectedRowIndex]["color"];
}
// 创建不透明的填充颜色
Color fillColor = selectedColor; // 直接使用选中的颜色,保持不透明
// 绘制填充矩形
g.FillRectangle(new SolidBrush(fillColor), _tempDiffTempRectangle);
// 绘制矩形边框线径固定为1以更精确控制绘制逻辑
using (Pen pen = new Pen(selectedColor, 1))
{
g.DrawRectangle(pen, _tempDiffTempRectangle);
}
}
}
// 触发重绘
picBoxTemp.Invalidate();
}
}
// 清空临时矩形
_tempDiffTempRectangle = Rectangle.Empty;
_isDrawingRectangle = false;
_rectangleStartPoint = Point.Empty;
}
@@ -1992,6 +1928,57 @@ namespace JoyD.Windows.CS
}
}
// 绘制温差图模式下的临时矩形预览
if (!_tempDiffTempRectangle.IsEmpty && _isTempDiffDrawingMode && _isDrawingRectangle)
{
// 将图像坐标转换为控件坐标
Rectangle controlRect = ImageRectangleToControlRectangle(_tempDiffTempRectangle);
// 获取当前选中的温差图例颜色
Color selectedColor = Color.Black; // 默认颜色
int selectedRowIndex = -1;
// 尝试获取选中行的颜色
if (dataGridViewTempDiff.SelectedRows.Count > 0)
{
selectedRowIndex = dataGridViewTempDiff.SelectedRows[0].Index;
}
else if (dataGridViewTempDiff.SelectedCells.Count > 0)
{
selectedRowIndex = dataGridViewTempDiff.SelectedCells[0].RowIndex;
}
// 如果选中行索引有效,获取对应的颜色
if (selectedRowIndex >= 0 && selectedRowIndex < tempDiffData.Count)
{
selectedColor = (Color)tempDiffData[selectedRowIndex]["color"];
}
if (_isEraseMode)
{
// 擦除模式使用白色虚线框
using (Pen dashedPen = new Pen(Color.White, 1))
{
dashedPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
e.Graphics.DrawRectangle(dashedPen, controlRect);
}
}
else
{
// 绘制模式使用半透明填充和边框
using (Pen dashedPen = new Pen(selectedColor, 1))
{
dashedPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
// 创建半透明的填充颜色
Color fillColor = Color.FromArgb(64, selectedColor);
// 绘制半透明填充
e.Graphics.FillRectangle(new SolidBrush(fillColor), controlRect);
// 绘制虚线边框
e.Graphics.DrawRectangle(dashedPen, controlRect);
}
}
}
// 再绘制临时矩形(当前正在绘制的矩形,使用控件坐标)
if (!_currentRectangle.IsEmpty && _isDrawingMode && _isDrawing)
{