1

I'm trying to use the following code to copy a portion of the screen to a new location on my Windows form.

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);
}

The CopyFromScreen function appears to ignore any clips set before it.

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

Am I doing something wrong or is this just the wrong approach.

For context: I'm trying to mitigate a UI widescreen game issue by copying the HUD at the edges and to be centered closer to the middle.

I am aware of FlawlessWidescreen, but it doesn't support many less popular games. I suppose poking around in memory (what flawless does) could also work but is almost always against TOS.

Edit: final goal is to copy some arbitrary path as the shape rather than a simple rectangle (I was hoping from an image mask).

Edit #2: So I have an irregular shape being drawn every 100ms. It turns out it just bogs the game down until I slow it down to every 500ms. But still the game isn't smooth. Is this operation of copying and drawing an image just going to be too heavy of an operation in GDI+? I was thinking it was simple enough to not bog anything down.

Thoughts before I mark the answer as accepted?

aitee
  • 91
  • 1
  • 1
  • 9

2 Answers2

2

I guess it is indeed the wrong approach.

The ClippingRegion is only used for clipping the DrawXXX and FillXXX commands, including DrawImage (!).

The CopyFromScreen however will use the given Points and Size and not clip the source.

For a Rectangle region this is no problem since you can achieve the same result by choosing the right Point and Size values.

But once you aim at using more interesting clipping regions you will have to use an intermediate Bitmap onto which you copy from the screen and from which you can then use DrawImage into the clipped region.

For this you can create more or less complicated GraphicsPaths.

Here is a code example:

After putting the cliping coordinates into a Rectangleor GraphicsPath clip you can write something like this:

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);
}
TaW
  • 53,122
  • 8
  • 69
  • 111
  • Thanks. I actually started to go down that road. I hadn't quite gotten my head around Graphics vs Bitmaps. and now I think I get it. The graphics is just a wrapper around some other source. So whether it be an HDC or an image, it doesn't matter. But you never copy graphics, you have to look at the source of what the graphic points to. – aitee Feb 15 '15 at 17:30
  • Yes: The Graphics class is a tool you use to work with a Bitmap of some source, be it a file or a control surface or a pure memory bitmap; it has many methods and some properties to control the way it works but it contains nor graphics data, i.e. no pixels. – TaW Feb 15 '15 at 18:00
  • Did you have any comment on Edit#2 ? Is a simple image copy outside the range for performance for GDI+? – aitee Feb 15 '15 at 20:56
  • Didn't notice the edit, sorry. GDI animation is usually hitting its limits rather soon. You can cache the GraphicsPath but I guess the speed mostly depends on the size of the copied areas. About what sizes do you use? – TaW Feb 15 '15 at 21:01
  • yeah, I can imagine that this could be somewhat jerky. – TaW Feb 15 '15 at 21:58
0

Shouldn't it be

 e.Graphics.Clip = myRegion;
tumasgiu
  • 325
  • 3
  • 11
  • Yes, sorry about that. I didn't just copy my code in to keep it concise (typed in the relevant parts). What I actually had in my code was `e.Graphics.SetClip(...);`. I assume/believe there is no difference to this and what you posted. – aitee Feb 15 '15 at 17:37