We do some pretty neat things with all sorts of code, and all this requires a ton of screenshots to help explain all the craziness. But besides having that good ol' fashion "Print Screen" button, we can actually use C# to take a screenshot for us. The best part of all is that it is only a couple lines of code. So lets just go ahead and dive right into it.
Now, all we are going to do is create a function that you can call whenever you need to take a screenshot. The first thing we need to do is add a using statement, because we are going to use a non-standard namespace. We need to include the System.Drawing.Imaging namespace in order for this to work:
Using System.Drawing.Imaging;
That will let us use the basic yet powerful methods that will help take a screenshot. The first thing we need to do is setup an empty method to fill up. To start, our method will take in nothing and return a bitmap, so it will look something like this:
public Bitmap ScreenShot()
{
}
Simple enough, right? Even better, technically to get a basic screenshot we need only 3 lines of code in this function. The first line will be a declaration for a new bitmap object:
Bitmap screenShotBMP = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
All we are doing is making a standard C# Bitmap object that is the size of the primary display on the computer. The Screen class has some pretty neat stuff, but that is for later, now we must create a Graphics object:
Graphics screenShotGraphics = Graphics.FromImage(screenShotBMP);
Put simply, this object helps set up a canvas, but a graphics object also helps with the drawing as well. Oddly enough, this class has a method called CopyFromScreen. Yep, you guessed it, this is the method that copies a portion of the screen for us. We will be using the screen object again to get the size of the screen. For the first screenshot we will just get the whole thing:
screenShotGraphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
All this line does is copy a portion of the screen, the whole screen in this case, in a specific format. With those 3 lines of code, we have a Bitmap object filled with a nice screen-size screenshot. All that is left for this method is to return the bitmap object. The final version will look like so:
public Bitmap ScreenShot()
{
Bitmap screenShotBMP = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
Graphics screenShotGraphics = Graphics.FromImage(screenShotBMP);
screenShotGraphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
screenShotGraphics.Dispose();
return screenShotBMP;
}

Wait, wait a second. This method does some justice if you have one screen, but what kind of developer has only one screen? Well, thankfully the screen class has this handy Screen array that holds the information for all the screens on the system. The only issue is that we have to loop through all the Screens to get the information we need. The good flip side is that this fix will handle 2, 3, or however many screens wide.
As with any addition to a program, we have to add some new variables. Actually we only need one new variable that will go at the top of our ScreenShot method:
Rectangle totalSize = Rectangle.Empty;
This one variable will hold all the screen size data for all of the screens on the current computer. These screens can be any different size in any order, it doesn't matter, the method will catch it.
So now that we have our nice empty rectangle, we can go ahead and fill it with the needed screen size information. First we must loop through the Screens in the screens array. For each screen, we need to take the Bounds member and take its information (in rectangle form) and then add it to totalSize. The whole loop is actually just one line, so we can use the one-liner no-bracket shortcut:
foreach (Screen s in Screen.AllScreens)
totalSize = Rectangle.Union(totalSize, s.Bounds);
All we are doing here is using a little static method called Rectangle.Union, which adds two rectangles together and returns the new rectangle. So for each screen, we just add the Bounds rectangle to the current totalSize object. When the loop is finished, we have a pretty filled rectangle, the size of all the screens combined.
The last step in this process is to change around our original code. We need to change 3 things: The width and height of our bitmap, and the size passed to the CopyFromScreen call. So, after those changes, the final method is:
public Bitmap ScreenShot()
{
Rectangle totalSize = Rectangle.Empty;
foreach (Screen s in Screen.AllScreens)
totalSize = Rectangle.Union(totalSize, s.Bounds);
Bitmap screenShotBMP = new Bitmap(totalSize.Width, totalSize.Height,
PixelFormat.Format32bppArgb);
Graphics screenShotGraphics = Graphics.FromImage(screenShotBMP);
screenShotGraphics.CopyFromScreen(totalSize.X, totalSize.Y,
0, 0, totalSize.Size, CopyPixelOperation.SourceCopy);
screenShotGraphics.Dispose();
return screenShotBMP;
}
All we are doing in our final changes is using our totalSize rectangle object to set the size of the bitmap and graphics object, as opposed to using Screen.PrimaryScreen. The sets all the objects we use to the right size to accommodate all the screens on the computer. With this method, you can get a screenshot from almost any computer setup. The final result will look something like:

Now this will return a Bitmap object, which can be used any number of
ways. The Bitmap class actually has a Save method that takes in a path
and image format, so you can actually save the image with one line of
code. You can also use a picture box and view a shrunk down version of
your screenshot. Anything that you can do with a Bitmap object, you can
do with your screenshot. You can also tweak the numbers passed into the
CopyFromScreen method if you only want a portion of the screen.
And with that, this tutorial wraps up. A Full Visual Studio Solution can be found here,.
Source Files:
gr8 work!!
Yhanks buddy you saved my lot of work !
is bitmap a class?????since the error is generatd when i copy pasted dis code....and what is copy pixelposition????????
Hey where does the BMP get saved? and if it doesnt, how do you save it to a new folder? i want to make a screen recorder (i have everything else under control its just the saving of the bitmap)
All you have to do is call Save on the Bitmap object that's created.
Thanx, it works gr8 ;)
Cool. I've never been aware all that time that Graphics class has a CopyFromScreen method!
is it possible to take picture from a playing movie in overlay
thanks...
Thank you so much for this code. I tested it out on my Windows 7 x64 Desktop and launched World of Warcraft. It took the Picture correctly. Tried the same code on my laptop (Windows 7 x86)and now I am getting a different result. It seems to be giving me a screen shot of my desktop and not of the game that is actually open.
It looks like the issue is related to (Aero vs Classic) themes. Once that is turned to classic the game is able to get captured. I wonder if there is a way around that?
awesome!
Your code will leak handles. You should really dispose the Graphics-object and the Bitmap at the end.
very nice ... :D