Click here to Skip to main content
Click here to Skip to main content

Tagged as

Screen Capture in WPF & WinForms Application

, 5 Jul 2010
Rate this:
Please Sign up or sign in to vote.
The post will demonstrate how you can capture a snapshot of a screen from within the application itself.

I was wondering how one can capture a screenshot from an application. I saw many applications were doing them. This thought got me interested in writing an application that can take a screen shot. In this article, I will demonstrate how one can take a screen shot directly from the Desktop area using WinForms and WPF.

WinForms Application

In WinForms application, it is very easy to grab a screen snapshot. To do this, you only need to create an object of Bitmap, on which you want to draw the image, get Graphics object from the Bitmap and then use CopyFromScreen method to actually draw the image into the Bitmap. To demonstrate, let us consider this method:

public void CaptureScreen(double x, double y, double width, double height)
 {
            int ix, iy, iw, ih;
            ix = Convert.ToInt32(x);
            iy = Convert.ToInt32(y);
            iw = Convert.ToInt32(width);
            ih = Convert.ToInt32(height);
            Bitmap image = new Bitmap(iw, ih, 
                   System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            Graphics g = Graphics.FromImage(image);
            g.CopyFromScreen(ix, iy, ix, iy, 
                     new System.Drawing.Size(iw, ih), 
                     CopyPixelOperation.SourceCopy);
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.DefaultExt = "png";
            dlg.Filter = "Png Files|*.png";
            DialogResult res = dlg.ShowDialog();
            if (res == System.Windows.Forms.DialogResult.OK)
                image.Save(dlg.FileName, ImageFormat.Png);
 }

The above code takes Start X, Start Y, width and height and saves the image into the disk. In this method, I created an object of Bitmap where I would be drawing the image. There are large number of PixelFormats supported by the Bitmap object. You can choose any one of them which suits you. As I am working on a 32 Bit true color environment, I used Format32bppArgb.

After doing this, you need to actually draw into the Bitmap object. To do this, you need to get graphics object from the image. I used Graphics.FromImage(image) to grab the graphics object from the image, so that the graphics could draw into the Bitmap object.

Finally I called g.CopyFromScreen which actually captures the screen snapshot, just like what Screenshot does and writes on the Bitmap. The argument that I have passed determines the dimension of the image. The x, y, width and height determines where from on the screen the snapshot should start and its width and height upto where it must go. At last, I used image.Save to save the image in PNG format in the disk.

You should note, if you want transparency in your image, you should use PNG, as it supports transparency.

A Little Depth

If you want to know what exactly happens in background, let us use DllImport to demonstrate the concept. Actually Screen capture is made using an API call to BitBlt. This method can be called with appropriate dimension just as the managed method CopyFromScreen, and gets the image.

To implement using Native code:

internal class NativeMethods
{
    [DllImport("user32.dll")]
     public extern static IntPtr GetDesktopWindow();
    [DllImport("user32.dll")]
    public static extern IntPtr GetWindowDC(IntPtr hwnd);
    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern IntPtr GetForegroundWindow();
    [DllImport("gdi32.dll")]
    public static extern UInt64 BitBlt(IntPtr hDestDC, int x, int y, 
       int nWidth, int nHeight, IntPtr hSrcDC, 
       int xSrc, int ySrc, System.Int32 dwRop);
}

The NativeMethod BitBlt is actually the most useful method in this context. To grab the image using this, you can use:

public void SaveScreen(double x, double y, double width, double height)
{
      int ix, iy, iw, ih;
      ix = Convert.ToInt32(x);
      iy = Convert.ToInt32(y);
      iw = Convert.ToInt32(width);
      ih = Convert.ToInt32(height);
      try
      {
          Bitmap myImage = new Bitmap(iw, ih);
          Graphics gr1 = Graphics.FromImage(myImage);
          IntPtr dc1 = gr1.GetHdc();
          IntPtr dc2 = NativeMethods.GetWindowDC(NativeMethods.GetForegroundWindow());
         NativeMethods.BitBlt(dc1, ix, iy, iw, ih, dc2, ix, iy, 13369376);
         gr1.ReleaseHdc(dc1);
         SaveFileDialog dlg = new SaveFileDialog();
         dlg.DefaultExt = "png";
         dlg.Filter = "Png Files|*.png";
         DialogResult res = dlg.ShowDialog();
         if (res == System.Windows.Forms.DialogResult.OK)
             myImage.Save(dlg.FileName, ImageFormat.Png);
       }
       catch { }
 }

In this function, I am doing the same thing that I did for the earlier one. The difference is that, here I am using NativeMethod to invoke the BitBlt directly rather than using the Managed code CopyFromScreen method.

If you want to capture the whole working area, you can use:

  • Screen.PrimaryScreen.Bounds.X
  • Screen.PrimaryScreen.Bounds.Y
  • Screen.PrimaryScreen.Bounds.Width, and
  • Screen.PrimaryScreen.Bounds.Height

as its arguments.

Sample Application

In this sample application, you will find a WPF application that allows you to capture a part of the screen. Let's look at how it works:

  1. Run the application, you will be provided with a screen where you can drag the mouse to take a screenshot.

  2. After you drag the mouse and Release the mouse, you will see a dialog box to save the image.

  3. Finally after you save, you will see the snapshot in PNG format.

Thus, it is very easy to work with Screen capture.

I hope you will like this application.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Abhishek Sur
Architect
India India
Did you like his post?
 
Oh, lets go a bit further to know him better.
Visit his Website : www.abhisheksur.com to know more about Abhishek.
 
Abhishek also authored a book on .NET 4.5 Features and recommends you to read it, you will learn a lot from it.
http://bit.ly/EXPERTCookBook
 
Basically he is from India, who loves to explore the .NET world. He loves to code and in his leisure you always find him talking about technical stuffs.
 
Presently he is working in WPF, a new foundation to UI development, but mostly he likes to work on architecture and business classes. ASP.NET is one of his strength as well.
Have any problem? Write to him in his Forum.
 
You can also mail him directly to abhi2434@yahoo.com
 
Want a Coder like him for your project?
Drop him a mail to contact@abhisheksur.com
 
Visit His Blog

Dotnet Tricks and Tips



Dont forget to vote or share your comments about his Writing
Follow on   Twitter   Google+

Comments and Discussions

 
SuggestionShould provide link to the original code, otherwise it's a Plagiat Pinmemberalexbk6614-Jan-14 14:51 
GeneralMy vote of 4 PinmemberLife Owner23-Apr-13 1:13 
QuestionWhy it can't use mouse_Up in WPF Pinmemberpiseysen27-Feb-13 23:41 
GeneralMy vote of 1 Pinmemberfirstvic30-Aug-12 10:35 
GeneralRe: My vote of 1 PinmemberAbhishek Sur30-Aug-12 12:56 
QuestionIs it the same code? Pinmembervkuzmich30-Aug-12 9:44 
AnswerRe: Is it the same code? PinmemberAbhishek Sur30-Aug-12 12:56 
GeneralIt works fine Pinmembermarc200013-Jul-10 1:37 
the sample app start without frame window, just use the mouse to select screen.
GeneralRe: It works fine PinmvpAbhishek Sur14-Jul-10 9:11 
GeneralMy vote of 1 Pinmembersodem12-Jul-10 20:54 
GeneralRe: My vote of 1 PinmvpAbhishek Sur14-Jul-10 9:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140827.1 | Last Updated 5 Jul 2010
Article Copyright 2010 by Abhishek Sur
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid