我的目标是在表单上绘制图像(屏幕截图)并使用橡皮筋矩形突出显示选定区域。我希望图像变暗并且选择区域正常。
我试图通过使用鼠标事件来获取用户选择的区域,在表单上绘制图像,然后使用区域(用于变暗/突出显示效果)在图像上绘制不透明的黑色叠加层来实现这一点,除了使用以下代码选择区域:
class ExampleForm : Form {
private Bitmap screenshot;
private Rectangle r;
private Region reg;
private SolidBrush brush;
public ExampleForm() {
r = Screen.PrimaryScreen.Bounds;
screenshot = new Bitmap(r.Width, r.Height);
Graphics.FromImage(screenshot).CopyFromScreen(r.Left, r.Top, 0, 0, r.Size);
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
FormBorderStyle = FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
TopMost = true;
DoubleBuffered = true;
ShowInTaskbar = false;
reg = new Region(r);
brush = new SolidBrush(Color.FromArgb(200, Color.Black));
}
private Point startDrag, endDrag;
private bool mouseDown;
protected override void OnMouseDown(MouseEventArgs e) {
mouseDown = true;
startDrag = e.Location;
}
protected override void OnMouseUp(MouseEventArgs e) {
mouseDown = false;
}
protected override void OnMouseMove(MouseEventArgs e) {
if (!mouseDown) return;
endDrag = e.Location;
UpdatePaint();
}
private void UpdatePaint() {
Rectangle window = new Rectangle(
Math.Min(startDrag.X, endDrag.X),
Math.Min(startDrag.Y, endDrag.Y),
Math.Abs(startDrag.X - endDrag.X),
Math.Abs(startDrag.Y - endDrag.Y)
);
reg = new Region(ClientRectangle);
reg.Xor(window);
Invalidate();
}
protected override void OnPaint(PaintEventArgs e) {
Graphics g = e.Graphics;
g.DrawImage(screenshot, r);
g.FillRegion(brush, reg);
}
}
但是,这样做时,在我移动鼠标和“突出显示”区域更新到鼠标位置之间存在相当大的延迟。
我试图在没有图像的情况下进行区域突出显示,甚至只是在没有图像和区域的情况下绘制一个矩形,并且延迟更少,但是与 Windows 资源管理器突出显示或 lightshot 之类的东西相比(这就是我想要的功能重新创建)在鼠标移动和表单中显示的内容之间仍然存在更多延迟。
我什至尝试使用两种形式:一种用于图像,另一种用于变暗/高亮效果,因此不必每次都重新绘制图像,但无法在顶部绘制不透明颜色的同时使表单透明。
我也尝试过 OnPaintBackground,使用标签或图像框,但都有相同的延迟。
那么有没有更有效的方法来进行绘图和/或我使用的突出显示效果?