VB.NET WinForms截图工具:替代ExcludeClip实现选区遮罩
解决VB.NET WinForms截图工具遮罩与手绘冲突问题
问题核心
原方案用e.Graphics.ExcludeClip(ctrlResize.Bounds)实现选区外半透明黑遮罩,但该操作会修改绘图上下文的裁剪区域,导致后续PictureBox Paint事件中绘制的箭头、矩形、手绘内容被排除在显示范围外。移除ExcludeClip后手绘正常,但失去遮罩效果。
替代方案:路径组合实现遮罩挖空
无需修改裁剪区域,通过绘制全屏半透明遮罩并挖空选区区域的方式实现需求,既保留遮罩效果,又不影响上层控件的绘制。
核心代码实现
在自定义透明UserControl的Paint事件中,使用GraphicsPath组合全屏区域与选区区域,填充半透明黑色作为遮罩:
Private Sub ucScreenCapture_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint ' 启用高质量渲染 e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias e.Graphics.CompositingQuality = Drawing2D.CompositingQuality.HighQuality e.Graphics.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic ' 定义全屏区域(匹配UserControl大小,若覆盖整个屏幕则用Screen.PrimaryScreen.Bounds) Dim fullArea As New Rectangle(0, 0, Me.Width, Me.Height) ' 选区区域(你的选区控件Bounds) Dim selectionArea As Rectangle = ctrlResize.Bounds ' 创建遮罩路径:全屏区域减去选区区域 Using maskPath As New Drawing2D.GraphicsPath() maskPath.AddRectangle(fullArea) maskPath.AddRectangle(selectionArea) ' 交替填充模式会自动排除重叠区域(即挖空选区) maskPath.FillMode = Drawing2D.FillMode.Alternate ' 绘制半透明黑色遮罩(Alpha值180可根据需求调整) Using maskBrush As New SolidBrush(Color.FromArgb(180, 0, 0, 0)) e.Graphics.FillPath(maskBrush, maskPath) End Using End Using End Sub
方案说明
- 原理:通过
GraphicsPath的FillMode.Alternate属性,当添加两个矩形路径时,重叠区域会被自动排除,从而实现选区外遮罩、选区透明的效果。 - 优势:未修改绘图上下文的裁剪区域,PictureBox的Paint事件可以正常在选区区域绘制箭头、矩形等内容,不会被裁剪。
- 注意事项:确保PictureBox控件位于UserControl的上层(可通过控件的
BringToFront()方法调整层级),避免遮罩覆盖手绘内容。
内容的提问来源于stack exchange,提问作者Luiz
相关产品推荐
相关产品推荐

