Geekpedia Programming Tutorials






Capturing screenshots using C#

This tutorial will show you a very simple method of capturing screenshots using C# and .NET 2.0 and saving them as files with different formats, such as PNG, all thanks to the CopyFromScreen() method.

On Saturday, April 22nd 2006 at 01:32 PM
By Andrew Pociu (View Profile)
*****   (Rated 4.8 with 50 votes)
Contextual Ads
More C# Resources
Advertisement
Download this Visual Studio 2005 project Download this project (Visual Studio 2005)

On the web, there are a few tutorials that will show you how to make a screen capture similar to the one that's created and stored in the clipboard when the "Print Screen" button is pressed. However, you will find that these tutorials are a bit too complicated for such a simple task. In this tutorial we're going to accomplish the same thing those tutorials do, but with only a few lines of code, thanks to the .NET 2.0 Framework, that introduced the new CopyFromScreen() method.

Screenshot Capture

Start by creating a new Windows Application project in Visual Studio 2005. Add to it a button btnCapture and a SaveFileDialog control entitled saveScreenshot, which will be used to prompt the user to choose a path where he wants the screenshot saved.

Screenshot Capture Visual Studio 2005

Now switch to code view and add the following using statement below the already existent statements:


using System.Drawing.Imaging;


Also, inside the class declare these two objects we're going to use to capture and store the screenshot:


private static Bitmap bmpScreenshot;

private static Graphics gfxScreenshot;


The button - btnCapture - is where all the action will take place. So inside Visual Studio's the form designer, double click the button and the Click event will be created. Inside it, use the following code:


// If the user has chosen a path where to save the screenshot

if (saveScreenshot.ShowDialog() == DialogResult.OK)

{

   // Hide the form so that it does not appear in the screenshot

   this.Hide();

   // Set the bitmap object to the size of the screen

   bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

   // Create a graphics object from the bitmap

   gfxScreenshot = Graphics.FromImage(bmpScreenshot);

   // Take the screenshot from the upper left corner to the right bottom corner

   gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);

   // Save the screenshot to the specified path that the user has chosen

   bmpScreenshot.Save(saveScreenshot.FileName, ImageFormat.Png);

   // Show the form again

   this.Show();

}


As you can see in the code above, the first thing we do is to show the save dialog to the user so that he can choose the path where he wants the screenshot to be saved. The next thing we do is hide the form so that it does not appear in the screenshot. After that, we are defining the two objects that were declared earlier, with information about the size of the image / screenshot (which is the desktop size). The screenshot is practically taken when the CopyFromScreen() method is called with the appropriate parameters. Then the Bitmap object saves it to the specified path, and format. We choosed PNG since it's a great file format, however you can choose from the most popular formats (Bmp, Gif, Jpeg, Tiff, etc.).

That's all you need to capture and save a screenshot in .NET 2.0. In case you prefer to have a look over the entire code of Form1.cs, you can view it below:


using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Drawing.Imaging;

 

namespace ScreenshotCapturer

{

    public partial class Form1 : Form

    {

        private static Bitmap bmpScreenshot;

        private static Graphics gfxScreenshot;

 

        public Form1()

        {

            InitializeComponent();

        }

 

        private void btnCapture_Click(object sender, EventArgs e)

        {

            // If the user has choosed a path where to save the screenshot

            if (saveScreenshot.ShowDialog() == DialogResult.OK)

            {

                // Hide the form so that it does not appear in the screenshot

                this.Hide();

                // Set the bitmap object to the size of the screen

                bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

                // Create a graphics object from the bitmap

                gfxScreenshot = Graphics.FromImage(bmpScreenshot);

                // Take the screenshot from the upper left corner to the right bottom corner

                gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);

                // Save the screenshot to the specified path that the user has chosen

                bmpScreenshot.Save(saveScreenshot.FileName, ImageFormat.Png);

                // Show the form again

                this.Show();

            }

        }

    }

}

Digg Digg It!     Del.icio.us Del.icio.us     Reddit Reddit     StumbleUpon StumbleIt     Newsvine Newsvine     Furl Furl     BlinkList BlinkList

Rate Rate this tutorial
Comment Current Comments
by Robert Hoath on Friday, April 28th 2006 at 01:01 PM

This works for my primary monitor, but how would I capture my second screen as well?

by Lee on Monday, May 1st 2006 at 12:52 AM

Instead of using Screens.PrimaryScreen you can loop through all the screens using the Screen.AllScreens array.

by on Sunday, May 28th 2006 at 09:30 PM

Error 1 The name 'saveScreenshot' does not exist in the current context C:\Documents and Settings\Kris\My Documents\Visual Studio 2005\Projects\RSDemona Frameset\RSDemona Frameset\Form1.cs 69 17 RSDemona Frameset

by Andrei Pociu on Monday, May 29th 2006 at 02:49 AM

You probably didn't add the <b>SaveFileDialog</b>.

by Murray on Thursday, June 22nd 2006 at 01:05 PM

This works great for capturing the entire screen, but what if I only want to capture the active window. (like alt-print screen)

by Andrei Pociu on Thursday, June 22nd 2006 at 03:10 PM

That is possible too since there is a method in .NET Framework 2.0 that allows you to capture the screenshot of a running process. I'll probably update the tutorial to include that if I get a chance.

by Burc on Friday, June 23rd 2006 at 07:50 PM

I am interested in capturing screenshots of the active window too. Which methods/classes in .NET Framework allow us to do it?

by vaibhav tripathi on Tuesday, July 4th 2006 at 03:21 AM

i want to develop an application in c# that detect the scanner in the network,that shows that the scanner is connected or dis-connected

by Chris on Monday, September 11th 2006 at 01:07 PM

Murray and Others:

For the active form, try replacing the screen.bounds statements with this.bounds

It works great for me, and applies if you want to capture the form's own window.

by S Winita on Tuesday, September 12th 2006 at 07:20 AM

How can we "video apature the active window"??

by Tom on Monday, January 8th 2007 at 05:26 PM

Hi,
This is almost exactly what I need. After capturing the image, I want to directly print it, not save to a file. How would I print it?

by Tom on Monday, January 8th 2007 at 05:27 PM

Hi,
This is almost exactly what I need. After capturing the image, I want to directly print it, not save to a file. How would I print it?

by John W on Sunday, January 14th 2007 at 04:23 AM

This works fine for SourceCopy, but SourceInvert doesn\'t seem to work correctly.

by John B on Sunday, March 11th 2007 at 03:25 PM

How to capture screens when my capture application works as a service on a local system account?

by Gajendra on Monday, April 30th 2007 at 05:59 AM

Hi,
Though we can capture the screen shot but after saving it i want to see the saved screen shot. How can i do it?

by Satheesh on Monday, April 30th 2007 at 04:43 PM

Hi,
I have a controller application which monitors another one and capture the screen time to time. This fails when I lock the screen.
(I am trying to get all screen image.) Could anyone help me to capture the screen even when the screen is locked?

by Balu on Tuesday, May 22nd 2007 at 06:30 AM

Nice posting..But,how can I achieve it in .Net 1.1..Any suggestions??

by VGstudios on Wednesday, July 11th 2007 at 09:32 PM

hi... can you tell me how to make a program kinda like hypercam???

by toast on Friday, August 17th 2007 at 06:51 PM

I want to cook some fried rice, what methods in c# will accomplish this?

Sound stupid? Take a minute to think about your question and if it sounds stupid, it probably is. What the hell does connecting scanners and writing applications that are like hypercam have to do with the article you chodes? NOTHING AT ALL

If this solution does not solve your problem (and you are obviously not smart enough to fill in the blanks because you are looking for the answers here) keep looking and quit asking idiotic questions.

by butter on Friday, August 24th 2007 at 09:30 AM

Toast,

I believe only VB currently provides fried rice cooking, you'll have to convert your c# application to FORTH.net and then once it compiles wrap it into a vb library before you can call the rice cooking API in system.cooking. Its a known limitation, but you know how those VB programmers can be when it comes to sharing things...

by Manish on Monday, September 10th 2007 at 01:43 AM

Thanks Pal You have reduced my work to 1/10. God Bless You!!
All the very best.

by Hi on Friday, January 25th 2008 at 05:04 AM

Hi,
I want capture the image behind my form.

by Ole on Monday, February 18th 2008 at 10:25 PM

hi how do i create remote video game? i want a game with capture screen :S?

by wing on Monday, March 10th 2008 at 12:24 AM

all this coding stuff is getting me hungry lol...

by EXPERT CODER on Wednesday, March 19th 2008 at 02:25 PM

HELLO I WANT CREATE FRIED RICE VIDEO GAME HOW DO I DO THIS THANKXS!!!!!!!!!!!!!!!!!!



by madhavi on Wednesday, June 25th 2008 at 06:54 AM

how can i write this.bounds for web application?
i want to capture my current, active window instead of complete desktop. for this query the this.bounds was applied only for windows application.

can u tell me for web application also.

Regards
Madhavi.

by JGuzman on Wednesday, July 2nd 2008 at 11:48 AM

To print the file, add this code inside btnCapture_Click after the file has been saved:

PrintDocument documentToPrint = new PrintDocument();
documentToPrint.PrintPage = new PrintPageEventHandler(documentToPrint_PrintPage);
documentToPrint.Print();


Then add this handler:

private void documentToPrint_PrintPage(object sender, PrintPageEventArgs e)
{
FileStream fs = new FileStream(saveScreenshot.FileName,FileMode.Open, FileAccess.Read);
System.Drawing.Image image = System.Drawing.Image.FromStream(fs);

int x = e.MarginBounds.X;
int y = e.MarginBounds.Y;
int width = image.Width;
int height = image.Height;

if ((width / e.MarginBounds.Width) > (height / e.MarginBounds.Height))
{
width = e.MarginBounds.Width;
height = image.Height * e.MarginBounds.Width / image.Width;
}
else
{
height = e.MarginBounds.Height;
width = image.Width * e.MarginBounds.Height / image.Height;
}
System.Drawing.Rectangle destRect = new System.Drawing.Rectangle(x, y, width, height);
e.Graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, System.Drawing.GraphicsUnit.Pixel);
}

by JGuzman on Wednesday, July 2nd 2008 at 01:45 PM

Also, make sure you add the following using statements:

using System.Drawing.Printing;
using System.IO;

by dharn on Friday, July 4th 2008 at 03:45 AM

thanks for ur code it gave me a nice idea

by madhavi on Thursday, July 10th 2008 at 01:57 AM

how can i write this.bounds for web application?
i want to capture my current, active window instead of complete desktop using asp.net. for this query the this.bounds was applied only for windows application.

can any one tell me for web application...

Regards
Madhavi.

by Eugene on Friday, July 18th 2008 at 02:23 AM

Thank you very much! You saved an hour of work for me! Very useful!

by You on Wednesday, July 30th 2008 at 04:37 PM

The only problem i see with this method is speed. I need to take snapshots 24 frames per sec. When i do this with this soft i get 100% of processor time. Any suggestions how to decrease this? Or i will be forced to use DirectShow

by Brad on Monday, September 15th 2008 at 01:38 PM

Great Application I have one question though. I would like this to automatically save the file to a default location for example c:\pic.bmp without any dialogs. I would use a timer control of course but having issues converting the image object to a binary or other form for file saving

by rick on Thursday, October 2nd 2008 at 01:59 PM

how can i write aprogram that will capture and store information about students i.d #, majore, 3 numeri(integer) grades.can someone help me on this one.

by ahmet on Tuesday, November 4th 2008 at 02:27 AM

exellent subject..
i must find like this code but another friend said too like that,"the code must do like
"alt - print screen". do you have any idea?

by madoo on Tuesday, November 4th 2008 at 03:10 AM

Use the above sample application and replace the screen.bounds to this.bounds for capture the active window(Alt PrintScreen)

The code given bellow....

private void btnCapture_Click(object sender, EventArgs e)
{
// If the user has chosen a path where to save the screenshot
if (saveScreenshot.ShowDialog() == DialogResult.OK)
{
// Hide the form so that it does not appear in the screenshot
this.Hide();
// Set the bitmap object to the size of the screen
bmpScreenshot = new Bitmap(this.Bounds.Width,this.Bounds.Height, PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap
gfxScreenshot = Graphics.FromImage(bmpScreenshot);
// Take the screenshot from the upper left corner to the right bottom corner
gfxScreenshot.CopyFromScreen(this.Bounds.X, this.Bounds.Y, 0, 0, this.Bounds.Size, CopyPixelOperation.SourceCopy);
// Save the screenshot to the specified path that the user has chosen
bmpScreenshot.Save(saveScreenshot.FileName, ImageFormat.Png);
// Show the form again
this.Show();
}
}

by ahmet on Tuesday, November 4th 2008 at 05:27 AM

thanks alot..
i did it :)
see you

by martin on Saturday, November 8th 2008 at 02:57 AM

the application works grt ...
but i wud like to know why the mouse pointer was not captured while taking the screenshot ?

by great on Saturday, January 24th 2009 at 10:05 PM

i liked it how do u did it>?>

by Wes on Friday, March 20th 2009 at 01:01 PM

Could I use this to take a screenshot of just 1 control in the form? I want to take a screenshot of a panel, but not the whole form. Thanks.

by Wes on Friday, March 20th 2009 at 01:01 PM

Could I use this to take a screenshot of just 1 control in the form? I want to take a screenshot of a panel, but not the whole form. Thanks.

by TJ on Wednesday, April 1st 2009 at 10:38 AM

Hello!
Is it possible to get a screenshot of a window that is not on the top, i.e. if it is partially hided by another window, without bringing it to the top?
Thanx
TJ

by Tom on Monday, July 20th 2009 at 03:06 AM

Hi Guys,

Great code!
But is there any possibility that you can controll the quality of the image before you save it?
For example, i'd like to save it as a jpeg file with quality 80. Is this possible?

Tnx,
Tom

by Jo on Thursday, August 13th 2009 at 09:45 PM

Hi,
My question is similar to madhavi's above. How can I get the window handles for a web application's page/browser window? A web page in .NET doesnt have the 'this.bounds' or 'Screen' options/properties. I am able to successfully use the GetDesktopWindow() etc to get a screen shot, but really need the "ALT PrintScreen" functionality for my web app's page and can't successfully get the bounds/pointer of my web page.
ANY HELP would be appreciated!!!!
Thanks!

by Vijay on Friday, August 21st 2009 at 03:44 AM

Hi friends,

I saw your posts and comments, they were really good. I want to do painting operations on Microsoft word document using c#, I am using Interop.Microsoft.Office.Core. But I am unnable to move further, can anyone help me on this issue

by hitesh on Wednesday, September 9th 2009 at 12:23 PM

hi,
Can anybody give me the solution that how can i save
the images taken to my folder directly.I mean i don't want to ask to save images.Just i press capture and it will directly save to my folder....

Thank you in advance.

by Calum on Thursday, December 3rd 2009 at 07:42 AM

In windows 7

by arun on Friday, December 11th 2009 at 02:36 AM

Is there any method to capture the remote desktop screen.... can u suggest a way to do it.....

by Johar Ali on Monday, December 21st 2009 at 02:02 PM

Thanks Allot buddy :) :) :)

by ihtesham on Thursday, January 21st 2010 at 03:56 PM

Can i create a windows service, which will keep catpuring the screen say every 30 seconds and saving it to a database in a binary format using your way of capturing.

Nice post though.

by ihtesham on Thursday, January 21st 2010 at 03:56 PM

Can i create a windows service, which will keep catpuring the screen say every 30 seconds and saving it to a database in a binary format using your way of capturing.

Nice post though.

by IFreezeZer0 on Thursday, February 18th 2010 at 11:21 PM

Yu Should Put How To Show Save Dialog Box Save As

by Fro on Friday, April 2nd 2010 at 02:06 PM

hi, I need to make a proje for my univercity..İt is like this project. Mine is Desktop Video Capture on C#... Can Someone help me ?

by Sandeep on Wednesday, April 21st 2010 at 10:32 AM

Hi,
I used this


Comment Comment on this tutorial
Name: Email:
Message:
Comment Related Tutorials
There are no related tutorials.

Comment Related Source Code
There is no related source code.

Jobs C# Job Search
My skills include:
Enter a City:

Select a State:


Advanced Search >>
Advertisement

Free Magazine Subscriptions

Today's Pictures

Today's Video

Other Resources

Latest Download

Latest Icons