Capturing screenshots in C#

By FoxLearn 2/17/2025 8:23:48 AM   75
Capturing screenshots in C# can be done in several ways, depending on the specific requirements of your application (e.g., capturing the entire screen, a specific window, or a selected region).

Below are the common methods to capture screenshots in C# using System.Drawing and other libraries.

To start, if you want to utilize the ScreenCapture class, you must include the following class in your project.

public class ScreenCapture
{
    public Image CaptureScreen()
    {
        return CaptureWindow(User32.GetDesktopWindow());
    }

    public Image CaptureWindow(IntPtr handle)
    {
        IntPtr hdcSrc = User32.GetWindowDC(handle);
        User32.RECT windowRect = new User32.RECT();
        User32.GetWindowRect(handle, ref windowRect);
        int width = windowRect.right - windowRect.left;
        int height = windowRect.bottom - windowRect.top;
        IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
        IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
        IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
        GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
        GDI32.SelectObject(hdcDest, hOld);
        GDI32.DeleteDC(hdcDest);
        User32.ReleaseDC(handle, hdcSrc);
        Image img = Image.FromHbitmap(hBitmap);
        GDI32.DeleteObject(hBitmap);
        return img;
    }

    public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)
    {
        Image img = CaptureWindow(handle);
        img.Save(filename, format);
    }

    public void CaptureScreenToFile(string filename, ImageFormat format)
    {
        Image img = CaptureScreen();
        img.Save(filename, format);
    }

    private class GDI32
    {
        public const int SRCCOPY = 0x00CC0020;

        [DllImport("gdi32.dll")]
        public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjectSource, int nXSrc, int nYSrc, int dwRop);
        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight);
        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
        [DllImport("gdi32.dll")]
        public static extern bool DeleteDC(IntPtr hDC);
        [DllImport("gdi32.dll")]
        public static extern bool DeleteObject(IntPtr hObject);
        [DllImport("gdi32.dll")]
        public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
    }

    private class User32
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left, top, right, bottom;
        }

        [DllImport("user32.dll")]
        public static extern IntPtr GetDesktopWindow();
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowDC(IntPtr hWnd);
        [DllImport("user32.dll")]
        public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
    }
}

Capturing the Active Window

There are two main ways to capture a screenshot of the active window one involves using the ScreenCapture class, and the other uses the CopyFromScreen method directly from the Graphics class in .NET.

Using ScreenCapture Class

To capture a screenshot of the active window, use the following method:

private void CaptureActiveWindow(string filepath, string filename, ImageFormat format)
{
    ScreenCapture sc = new ScreenCapture();
    string fullpath = filepath + "\\" + filename;
    sc.CaptureWindowToFile(this.Handle, fullpath, format);
}

Usage example:

CaptureActiveWindow(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "window_screenshot.jpg", ImageFormat.Jpeg);

Using Graphics.CopyFromScreen Method

Alternatively, use the Graphics.CopyFromScreen method to capture the screenshot without the need for an external class.

private void CaptureActiveWindow(string filepath, string filename, ImageFormat format)
{
    Rectangle bounds = this.Bounds;

    using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
    {
        using (Graphics g = Graphics.FromImage(bitmap))
        {
            g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
        }

        string fullpath = filepath + "\\" + filename;
        bitmap.Save(fullpath, format);
    }
}

Usage example:

CaptureActiveWindow(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "window_screen_noclass.jpg", ImageFormat.Jpeg);

Capturing a Fullscreen Screenshot

There are also two methods for capturing a fullscreen screenshot: one using Graphics.CopyFromScreen and the other using the ScreenCapture class.

Using Graphics.CopyFromScreen

private void CaptureFullScreen(string filepath, string filename, ImageFormat format)
{
    Rectangle bounds = Screen.GetBounds(Point.Empty);
    using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
    {
        using (Graphics g = Graphics.FromImage(bitmap))
        {
            g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
        }

        string fullpath = filepath + "\\" + filename;
        bitmap.Save(fullpath, format);
    }
}

Usage example:

CaptureFullScreen(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "screenshot.jpg", ImageFormat.Jpeg);

Using ScreenCapture Class

private void CaptureFullScreen(string filepath, string filename, ImageFormat format)
{
    ScreenCapture sc = new ScreenCapture();
    Image img = sc.CaptureScreen();

    string fullpath = filepath + "\\" + filename;
    img.Save(fullpath, format);
}

Usage example:

CaptureFullScreen(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "screenshotfull_class.jpg", ImageFormat.Jpeg);

Capturing a Specific Region of the Screen

You may also want to capture a specific portion of the screen, not the entire screen or a window. In that case, you can define the region (x, y, width, height) to capture:

public void CaptureRegion(string filepath, string filename, ImageFormat format, Rectangle region)
{
    // Create a bitmap for the region to capture
    using (Bitmap bitmap = new Bitmap(region.Width, region.Height))
    {
        using (Graphics g = Graphics.FromImage(bitmap))
        {
            // Capture the specified region from the screen
            g.CopyFromScreen(region.Location, Point.Empty, region.Size);
        }

        // Save the screenshot of the region to a file
        string fullpath = System.IO.Path.Combine(filepath, filename);
        bitmap.Save(fullpath, format);
    }
}

Usage Example:

// Define the region to capture (x, y, width, height)
Rectangle region = new Rectangle(100, 100, 500, 400);
ScreenshotHelper helper = new ScreenshotHelper();
helper.CaptureRegion(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "region_screenshot.jpg", ImageFormat.Jpeg, region);

Additional Information

You can adjust the image format by changing the file extension and the ImageFormat type.

  • ImageFormat.Jpeg
  • ImageFormat.Gif
  • ImageFormat.Tiff
  • ImageFormat.Icon
  • ImageFormat.MemoryBmp
  • ImageFormat.Bmp
  • ImageFormat.Exif

By using the methods outlined here, you can easily integrate screenshot capture functionality into your C# WinForms applications, whether you need to capture a specific window or the entire screen.