You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在VB.NET画图类应用中实现绘制前光标处画笔预览效果?

实现画笔预览的方案

核心逻辑是拆分实际画布存储和临时预览层,预览内容仅在控件绘制时临时渲染,不会写入到实际画布的存储对象中,具体实现步骤如下:


1. 定义全局状态变量

首先添加必要的全局变量存储画布、画笔属性和鼠标状态:

' 存储实际画布内容,所有最终绘制的内容都会存在这里
Private canvasBmp As Bitmap
' 标记是否正在绘制(鼠标按住状态)
Private bStart As Boolean = False
' 画笔当前属性
Private brushSize As Integer = 10
Private brushColor As Color = Color.Red
' 记录当前鼠标位置
Private currentMousePos As Point = Point.Empty

2. 初始化画布

窗体加载时初始化和PictureBox尺寸一致的实际画布,同时开启控件双缓冲避免预览闪烁:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ' 初始化画布,底色设为白色
    canvasBmp = New Bitmap(pbPhoto.Width, pbPhoto.Height)
    Using g As Graphics = Graphics.FromImage(canvasBmp)
        g.Clear(Color.White)
    End Using
    pbPhoto.Image = canvasBmp
    ' 开启双缓冲减少闪烁
    pbPhoto.GetType().GetProperty("DoubleBuffered", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic).SetValue(pbPhoto, True, Nothing)
End Sub

3. 修改鼠标事件逻辑

鼠标移动时不再直接向PictureBox绘制内容,仅更新鼠标位置,按住时才将笔触写入实际画布:

Private Sub pbPhoto_MouseDown(sender As Object, e As MouseEventArgs) Handles pbPhoto.MouseDown
    If e.Button = MouseButtons.Left Then
        bStart = True
        ' 按下时直接绘制第一笔到实际画布
        Using g As Graphics = Graphics.FromImage(canvasBmp)
            g.FillEllipse(New SolidBrush(brushColor), e.X - brushSize \ 2, e.Y - brushSize \ 2, brushSize, brushSize)
        End Using
        pbPhoto.Invalidate()
    End If
End Sub

Private Sub pbPhoto_MouseMove(sender As Object, e As MouseEventArgs) Handles pbPhoto.MouseMove
    currentMousePos = e.Location
    ' 仅按住鼠标时才将笔触写入实际画布
    If bStart AndAlso e.Button = MouseButtons.Left Then
        Using g As Graphics = Graphics.FromImage(canvasBmp)
            g.FillEllipse(New SolidBrush(brushColor), e.X - brushSize \ 2, e.Y - brushSize \ 2, brushSize, brushSize)
        End Using
    End If
    ' 强制刷新控件触发绘制事件
    pbPhoto.Invalidate()
End Sub

Private Sub pbPhoto_MouseUp(sender As Object, e As MouseEventArgs) Handles pbPhoto.MouseUp
    bStart = False
    pbPhoto.Invalidate()
End Sub

4. 实现Paint事件绘制预览层

在PictureBox的Paint事件中先渲染实际画布,再在最上层临时绘制画笔预览,这部分内容不会写入canvasBmp,不会污染实际画布:

Private Sub pbPhoto_Paint(sender As Object, e As PaintEventArgs) Handles pbPhoto.Paint
    ' 先绘制实际画布内容
    e.Graphics.DrawImage(canvasBmp, Point.Empty)
    ' 未按住鼠标时绘制半透明预览笔触
    If Not bStart AndAlso currentMousePos <> Point.Empty Then
        Using previewBrush As New SolidBrush(Color.FromArgb(180, brushColor))
            e.Graphics.FillEllipse(previewBrush, currentMousePos.X - brushSize \ 2, currentMousePos.Y - brushSize \ 2, brushSize, brushSize)
        End Using
    End If
End Sub

补充说明

  • 调整画笔大小或颜色时,只需修改brushSize和brushColor变量的值,预览效果会自动更新
  • 坐标计算时减去画笔尺寸的一半,可保证笔触中心和光标位置完全对齐,和MS Paint的交互逻辑一致
  • 如果需要更高性能的预览,也可以将画笔形状生成自定义光标替换系统光标,这种方案无需频繁刷新控件,适合固定形状的画笔场景

内容的提问来源于stack exchange,提问作者Fame th

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 19:57:01