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:
Comments
Post a Comment