Taking Screenshots in C#

By FoxLearn 1/16/2025 7:37:54 AM   76
As developers, we often need to capture screenshots to help illustrate complex code, designs, or issues.

We’ll create a simple function that captures a screenshot whenever you need it.

The first step is to include the System.Drawing.Imaging namespace.

using System.Drawing.Imaging;

Creating the Screenshot Method

// Define a method that captures a screenshot of the primary screen and returns it as a Bitmap object.
public Bitmap ScreenShot()
{
    // Create a Bitmap object to hold the screenshot. The size of the Bitmap is set to match the primary screen's width and height.
    // The PixelFormat.Format32bppArgb specifies the image format with 32 bits per pixel, including an alpha channel for transparency.
    Bitmap screenShotBMP = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
        Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

    // Create a Graphics object that will be used to capture the screen's content and draw it onto the Bitmap.
    Graphics screenShotGraphics = Graphics.FromImage(screenShotBMP);

    // Capture the screen content by copying the entire area of the primary screen into the Bitmap.
    // The CopyFromScreen method takes the coordinates of the top-left corner of the screen, along with the size to copy (the entire screen).
    screenShotGraphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
        Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size,
        CopyPixelOperation.SourceCopy);

    // Dispose of the Graphics object after capturing the screenshot to free up system resources.
    screenShotGraphics.Dispose();

    // Return the Bitmap containing the screenshot.
    return screenShotBMP;
}

While the method above works great for single-screen setups, what if you have multiple monitors? We’ll need to loop through each screen and adjust our method accordingly.

// Define a method that captures a screenshot of all connected screens and returns it as a Bitmap object.
public Bitmap ScreenShot()
{
    // Initialize an empty Rectangle object to hold the combined bounds (area) of all connected screens.
    Rectangle totalSize = Rectangle.Empty;

    // Loop through each screen in the AllScreens collection and combine their bounds (screen areas) into the totalSize rectangle.
    // The Rectangle.Union method merges each screen's bounds with the current totalSize, ensuring we capture all screens.
    foreach (Screen s in Screen.AllScreens)
        totalSize = Rectangle.Union(totalSize, s.Bounds);

    // Create a Bitmap object to hold the screenshot. The size of the Bitmap is set to the combined dimensions of all screens.
    // The PixelFormat.Format32bppArgb specifies the image format with 32 bits per pixel, including an alpha channel for transparency.
    Bitmap screenShotBMP = new Bitmap(totalSize.Width, totalSize.Height,
        PixelFormat.Format32bppArgb);

    // Create a Graphics object that will be used to capture the content of all screens and draw it onto the Bitmap.
    Graphics screenShotGraphics = Graphics.FromImage(screenShotBMP);

    // Capture the content of all screens by copying the combined screen area (totalSize) into the Bitmap.
    // The CopyFromScreen method takes the coordinates of the top-left corner of the combined screen area and the size to copy.
    screenShotGraphics.CopyFromScreen(totalSize.X, totalSize.Y,
        0, 0, totalSize.Size, CopyPixelOperation.SourceCopy);

    // Dispose of the Graphics object after capturing the screenshot to free up system resources.
    screenShotGraphics.Dispose();

    // Return the Bitmap containing the screenshot of all connected screens.
    return screenShotBMP;
}

With this code, you can easily capture screenshots from any multi-monitor setup. The resulting Bitmap object can be used in a variety of ways, such as saving the image to a file, displaying it in a picture box, or further processing it.

To save the image, you can use the Save method of the Bitmap class:

screenShotBMP.Save("screenshot.png", ImageFormat.Png);

If you want to capture only a portion of the screen, you can modify the parameters passed to the CopyFromScreen method.