Click here to Skip to main content
11,412,516 members (69,322 online)
Click here to Skip to main content

Capturing the Screen Image in C#

, 27 Feb 2003
Rate this:
Please Sign up or sign in to vote.
An article on capturing the Screen using Win32 APIs in C#

Introduction

I am working on a desktop sharing type application in C#. First problem that I encountered was that there was not much in C# to capture the desktop image. After a bit of research I came to know that I shall have to use the Win32 APIs to provide this functionality to my application. I made following three classes to perform this job.

  1. PlatformInvokeGDI32: All the GDI32.dll APIs being used in this application are placed in this class.
  2. PlatformInvokeUSER32: All the User32.dll APIs have been placed in this class.
  3. CaptureScreen: In this class I have provided a simple static function GetDesktopImage that captures the screen image using the APIs  given in PlatformInvokeGDI32 and PlatformInvokeUSER32 and returns it as a bitmap.

You can very easily place these classes in your C# application. Just copy and paste following code in your C# project without changing any thing at all. If you want to use accompanying source files, you can  add the CaptureScreen namespace in your project or just change the CaptureScreen namespace in these classes with your project namespace and that's all.

The beautiful source code

/// <summary>
/// This class shall keep the GDI32 APIs used in our program.
/// </summary>
public class PlatformInvokeGDI32
{
#region Class Variables
    public const int SRCCOPY = 13369376;
#endregion
#region Class Functions<br>
    [DllImport("gdi32.dll",EntryPoint="DeleteDC")]
    public static extern IntPtr DeleteDC(IntPtr hDc);

    [DllImport("gdi32.dll",EntryPoint="DeleteObject")]
    public static extern IntPtr DeleteObject(IntPtr hDc);

    [DllImport("gdi32.dll",EntryPoint="BitBlt")]
    public static extern bool BitBlt(IntPtr hdcDest,int xDest,
        int yDest,int wDest,int hDest,IntPtr hdcSource,
        int xSrc,int ySrc,int RasterOp);

    [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleBitmap")]
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc,
        int nWidth, int nHeight);

    [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleDC")]
    public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

    [DllImport ("gdi32.dll",EntryPoint="SelectObject")]
    public static extern IntPtr SelectObject(IntPtr hdc,IntPtr bmp);
#endregion

#region Public Constructor
}

/// <summary>
/// This class shall keep the User32 APIs used in our program.
/// </summary>
public class PlatformInvokeUSER32
{
#region Class Variables
    public const int SM_CXSCREEN=0;
    public const int SM_CYSCREEN=1;
#endregion 

#region Class Functions
    [DllImport("user32.dll", EntryPoint="GetDesktopWindow")]
    public static extern IntPtr GetDesktopWindow();

    [DllImport("user32.dll",EntryPoint="GetDC")]
    public static extern IntPtr GetDC(IntPtr ptr);

    [DllImport("user32.dll",EntryPoint="GetSystemMetrics")]
    public static extern int GetSystemMetrics(int abc);

    [DllImport("user32.dll",EntryPoint="GetWindowDC")]
    public static extern IntPtr GetWindowDC(Int32 ptr);

    [DllImport("user32.dll",EntryPoint="ReleaseDC")]
    public static extern IntPtr ReleaseDC(IntPtr hWnd,IntPtr hDc);

#endregion
}

/// <summary>
/// This class shall keep all the functionality 
/// for capturing the desktop.
/// </summary>
public class CaptureScreen
{
#region Class Variable Declaration
    protected static IntPtr m_HBitmap;
#endregion

///
/// This class shall keep all the functionality for capturing
/// the desktop.
///
public class CaptureScreen
{
  #region Public Class Functions
  public static Bitmap GetDesktopImage()
  {
    //In size variable we shall keep the size of the screen.
    SIZE size;

    //Variable to keep the handle to bitmap.
    IntPtr hBitmap;

    //Here we get the handle to the desktop device context.
    IntPtr  hDC = PlatformInvokeUSER32.GetDC
                  (PlatformInvokeUSER32.GetDesktopWindow());

    //Here we make a compatible device context in memory for screen
    //device context.
    IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC);

    //We pass SM_CXSCREEN constant to GetSystemMetrics to get the
    //X coordinates of the screen.
    size.cx = PlatformInvokeUSER32.GetSystemMetrics
              (PlatformInvokeUSER32.SM_CXSCREEN);

    //We pass SM_CYSCREEN constant to GetSystemMetrics to get the
    //Y coordinates of the screen.
    size.cy = PlatformInvokeUSER32.GetSystemMetrics
              (PlatformInvokeUSER32.SM_CYSCREEN);

    //We create a compatible bitmap of the screen size and using
    //the screen device context.
    hBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap
                (hDC, size.cx, size.cy);

    //As hBitmap is IntPtr, we cannot check it against null.
    //For this purpose, IntPtr.Zero is used.
    if (hBitmap!=IntPtr.Zero)
    {
      //Here we select the compatible bitmap in the memeory device
      //context and keep the refrence to the old bitmap.
      IntPtr hOld = (IntPtr) PlatformInvokeGDI32.SelectObject
                             (hMemDC, hBitmap);
      //We copy the Bitmap to the memory device context.
      PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0,size.cx,size.cy, hDC,
                                 0, 0,PlatformInvokeGDI32.SRCCOPY);
      //We select the old bitmap back to the memory device context.
      PlatformInvokeGDI32.SelectObject(hMemDC, hOld);
      //We delete the memory device context.
      PlatformInvokeGDI32.DeleteDC(hMemDC);
      //We release the screen device context.
      PlatformInvokeUSER32.ReleaseDC(PlatformInvokeUSER32.
                                     GetDesktopWindow(), hDC);
      //Image is created by Image bitmap handle and stored in
      //local variable.
      Bitmap bmp = System.Drawing.Image.FromHbitmap(hBitmap); 
      //Release the memory to avoid memory leaks.
      PlatformInvokeGDI32.DeleteObject(hBitmap);
      //This statement runs the garbage collector manually.
      GC.Collect();
      //Return the bitmap 
      return bmp;
    }
    //If hBitmap is null, retun null.
    return null;
  }
  #endregion
}

//This structure shall be used to keep the size of the screen.
public struct SIZE
{
    public int cx;
    public int cy;
}

Conclusion

The demo application with this code shows the use of these classes. Its a very simple windows application in which there is a simple form having a menu and a picture box control. Capture Screen menu item of menu is used to capture the screen and assign to the image property of picture box control. I hope you like this code. I have commented each line of this code to make it self explanatory. If there is still something confusing for you, please let me know. Good Luck!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Agha Ali Raza
Web Developer
Pakistan Pakistan
No Biography provided

Comments and Discussions

 
QuestionLicensing information thought Pin
Member 10790768 at 13-May-14 11:11
memberMember 1079076813-May-14 11:11 
GeneralMy vote of 5 Pin
emanzer0 at 13-Jun-12 18:17
memberemanzer013-Jun-12 18:17 
GeneralRemote System Screen Capture Pin
sksaininet at 25-Dec-10 21:17
membersksaininet25-Dec-10 21:17 
Generalsimplier Pin
Lucian-aSterX at 15-Sep-10 2:19
memberLucian-aSterX15-Sep-10 2:19 
GeneralRe: simplier Pin
Horia Tudosie at 15-Jun-12 11:19
memberHoria Tudosie15-Jun-12 11:19 
GeneralNot working in game Pin
Shargon_85 at 15-Apr-10 23:59
memberShargon_8515-Apr-10 23:59 
GeneralThank you Pin
B.V.Papadopoulos at 4-Aug-09 22:16
memberB.V.Papadopoulos4-Aug-09 22:16 
GeneralMouse Position Pin
micoxXx at 3-Aug-08 8:44
membermicoxXx3-Aug-08 8:44 
GeneralRe: Mouse Position Pin
cheng_j_zhang at 11-Nov-08 18:04
membercheng_j_zhang11-Nov-08 18:04 
GeneralRe: Mouse Position Pin
cheng_j_zhang at 11-Nov-08 18:07
membercheng_j_zhang11-Nov-08 18:07 
GeneralDoesn't work when computer is locked Pin
JDBP at 4-Apr-08 5:57
memberJDBP4-Apr-08 5:57 
GeneralRe: Doesn't work when computer is locked [modified] Pin
romanof at 13-Feb-13 19:36
memberromanof13-Feb-13 19:36 
Generalmemory leak Pin
rattle5jonq at 8-Nov-07 8:48
memberrattle5jonq8-Nov-07 8:48 
GeneralDoing it with C# itself is much simpler... Pin
dalek9 at 30-Nov-06 9:06
memberdalek930-Nov-06 9:06 
GeneralRe: Doing it with C# itself is much simpler... Pin
El Chubb at 11-Jul-08 17:40
memberEl Chubb11-Jul-08 17:40 
GeneralRe: Doing it with C# itself is much simpler... Pin
micoxXx at 3-Aug-08 8:42
membermicoxXx3-Aug-08 8:42 
GeneralCopyFromScreen Pin
s.struck at 9-Sep-08 11:37
members.struck9-Sep-08 11:37 
GeneralRe: Doing it with C# itself is much simpler... Pin
snorkie at 9-Jul-09 10:54
membersnorkie9-Jul-09 10:54 
GeneralRe: Doing it with C# itself is much simpler... Pin
B.V.Papadopoulos at 4-Aug-09 22:17
memberB.V.Papadopoulos4-Aug-09 22:17 
QuestionVideo Pin
RichardUci at 7-Nov-06 6:12
memberRichardUci7-Nov-06 6:12 
GeneralDoesn't capture Layered (trasnparent, alpha blended) windows Pin
Jaykul at 9-Aug-05 9:14
memberJaykul9-Aug-05 9:14 
GeneralRe: Doesn't capture Layered (trasnparent, alpha blended) windows Pin
JonFrost at 19-Feb-07 21:09
memberJonFrost19-Feb-07 21:09 
GeneralNULL retured if I call the function 42 times Pin
raed at 23-Jun-05 4:10
memberraed23-Jun-05 4:10 
GeneralRe: NULL retured if I call the function 42 times Pin
Jaykul at 9-Aug-05 9:36
memberJaykul9-Aug-05 9:36 
GeneralMajor Memory Leak Pin
Falazar at 6-May-05 10:58
memberFalazar6-May-05 10:58 
GeneralRe: Major Memory Leak Pin
Jisu74 at 11-Nov-05 13:51
memberJisu7411-Nov-05 13:51 
GeneralRe: Major Memory Leak Pin
psyphen at 21-May-09 4:46
memberpsyphen21-May-09 4:46 
GeneralRe: Major Memory Leak Pin
jdohnoe at 7-Apr-10 14:36
memberjdohnoe7-Apr-10 14:36 
Generalthe Dll functions Pin
tokyo_bme at 2-Mar-05 8:36
membertokyo_bme2-Mar-05 8:36 
GeneralRe: the Dll functions Pin
jjreilly at 2-Mar-05 9:18
memberjjreilly2-Mar-05 9:18 
GeneralRe: the Dll functions Pin
tokyo_bme at 4-Mar-05 21:30
membertokyo_bme4-Mar-05 21:30 
Generalscreen capture in web app Pin
eheuer at 17-Feb-05 3:34
membereheuer17-Feb-05 3:34 
GeneralRe: screen capture in web app Pin
Timmy23 at 7-Mar-05 22:25
memberTimmy237-Mar-05 22:25 
GeneralBug with multiple monitors Pin
Sherrod Segraves at 24-Sep-04 6:52
sussSherrod Segraves24-Sep-04 6:52 
GeneralBlack screen???Help!!!!!!! Pin
WalkWorld at 5-Sep-04 20:05
memberWalkWorld5-Sep-04 20:05 
GeneralRe: Black screen???Help!!!!!!! Pin
deonvs at 28-Jul-09 14:59
memberdeonvs28-Jul-09 14:59 
QuestionOverlay? Pin
Jakub Florczyk at 22-Jul-03 23:59
memberJakub Florczyk22-Jul-03 23:59 
GeneralHelp with the remoting aspect Pin
UTAMav at 11-Jul-03 7:26
memberUTAMav11-Jul-03 7:26 
GeneralRe: Help with the remoting aspect Pin
Agha Ali Raza at 26-Jul-03 14:12
memberAgha Ali Raza26-Jul-03 14:12 
GeneralForm to bitmap (before it ever hits the screen) Pin
stantheman at 4-Mar-03 11:54
memberstantheman4-Mar-03 11:54 
GeneralAn alternative method Pin
Øyvind Rustan at 4-Mar-03 10:04
memberØyvind Rustan4-Mar-03 10:04 
QuestionHow much fun is it too... Pin
Cromwell at 4-Mar-03 9:53
memberCromwell4-Mar-03 9:53 
GeneralNot too shabby Pin
Richard A. Johnn at 1-Mar-03 20:01
memberRichard A. Johnn1-Mar-03 20:01 
General1000th Version of "Hello World" Pin
ProgrammerABCDEFG at 28-Feb-03 10:30
sussProgrammerABCDEFG28-Feb-03 10:30 
GeneralRe: 1000th Version of "Hello World" Pin
Tomáš Petříček at 28-Feb-03 12:32
memberTomáš Petříček28-Feb-03 12:32 
GeneralRe: 1000th Version of "Hello World" Pin
imaginejta at 1-Mar-03 6:23
memberimaginejta1-Mar-03 6:23 
GeneralRe: 1000th Version of "Hello World" Pin
Thomas A. Dzieran at 2-Mar-03 13:42
memberThomas A. Dzieran2-Mar-03 13:42 
GeneralSlow Hog Pin
Shawn Stevens at 28-Feb-03 9:34
memberShawn Stevens28-Feb-03 9:34 
GeneralRe: Slow Hog Pin
flipdoubt at 2-Mar-03 6:13
memberflipdoubt2-Mar-03 6:13 
GeneralRe: Slow Hog Pin
Shawn Stevens at 2-Mar-03 9:37
memberShawn Stevens2-Mar-03 9:37 

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 | Terms of Use | Mobile
Web04 | 2.8.150427.1 | Last Updated 28 Feb 2003
Article Copyright 2002 by Agha Ali Raza
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid