在表单上绘制之前在内存中剪切图形

Clipping a graphic in memory before drawing on form

我正在尝试使用以下代码将屏幕的一部分复制到我的 Windows 表单上的新位置。

private void Form1_Paint(object sender, PaintEventArgs e)
{
    var srcPoint = new Point(0,0);
    var dstPoint = new Point(Screen.PrimaryScreen.Bounds.Width/2, Screen.PrimaryScreen.Bounds.Height/2);
    var copySize = new Size(100, 100);

    e.Graphics.CopyFromScreen(srcPoint, dstPoint, copySize, CopyPixelOperation.SourceCopy);
}

CopyFromScreen 函数似乎忽略了之前设置的任何剪辑。

e.SetClip(new Rectangle(srcPoint.X, srcPoint.Y, 20, 20));

我是做错了什么还是这只是错误的方法。

对于上下文:我正在尝试通过复制边缘的 HUD 并靠近中间居中来缓解 UI 宽屏游戏问题。

我知道 FlawlessWidescreen,但它不支持许多不太流行的游戏。我想在内存中四处寻找(完美的做法)也可以工作,但几乎总是反对 TOS。

编辑:最终目标是复制一些任意路径作为形状而不是简单的矩形(我希望从图像蒙版中复制)。

编辑#2: 所以我每 100 毫秒绘制一个不规则的形状。事实证明,它只会让游戏陷入困境,直到我将它减慢到每 500 毫秒。但游戏仍然不流畅。这种复制和绘制图像的操作在 GDI+ 中会不会过于繁重?我在想这很简单,不会让任何事情陷入困境。

在我将答案标记为已接受之前的想法?

不应该是

 e.Graphics.Clip = myRegion;

我想这确实是错误的做法。

ClippingRegion仅用于裁剪DrawXXXFillXXX命令,包括DrawImage(!)。

但是 CopyFromScreen 将使用给定的 PointsSize 并且 而不是 剪辑源。

对于 Rectangle 区域,这没有问题,因为您可以通过选择正确的 PointSize 值来获得相同的结果。

但是一旦你打算使用更有趣的剪辑区域,你将不得不使用一个中间 Bitmap,你可以从屏幕上复制它,然后你可以使用 DrawImage 进入剪辑区域.

为此,您可以创建或多或少复杂的 GraphicsPaths

这是一个代码示例:

将裁剪坐标放入RectangleGraphicsPath clip后你可以这样写:

e.Graphics.SetClip(clip);

using (Bitmap bitmap = new Bitmap(ClientSize.Width, ClientSize.Height))
{
    using (Graphics G = Graphics.FromImage(bitmap))
            G.CopyFromScreen(dstPoint, srcPoint, 
                             copySize, CopyPixelOperation.SourceCopy);
    e.Graphics.DrawImage(bitmap, 0, 0);
}