Как программно сделать скриншот экрана C#

Приветствую всех! сегодня я покажу два примера того как можно сделать захват экрана, и сохранить скриншот у себя на компьютере. И так приступим первый вариант:

using System;
using System.Runtime.InteropServices;
using System.Drawing;

public class Program
{
    public static void Main()
    {

        Image f = CaptureScreen.GetDesktopImage();
        f.Save("D:\\1.jpeg");
    }
}
public class PlatformInvokeGDI32
{
    public const int SRCCOPY = 13369376;

    [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);

}

public class PlatformInvokeUSER32
{

    public const int SM_CXSCREEN = 0;
    public const int SM_CYSCREEN = 1;



    [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);


}

public class CaptureScreen
{

    protected static IntPtr m_HBitmap;



    public static Bitmap GetDesktopImage()
    {
        //В размер переменной мы должны сохранить размер экрана.
        SIZE size;

        //В размер переменной мы должны сохранить размер экрана.
        IntPtr hBitmap;

        //Здесь мы получаем дескриптор контекста устройства рабочего стола.
        IntPtr hDC = PlatformInvokeUSER32.GetDC
                      (PlatformInvokeUSER32.GetDesktopWindow());

        //Здесь мы делаем контекст устройства
       
        IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC);

        //Мы передаем SM_CXSCREEN константа GetSystemMetrics               // и получить X координаты экрана.
        size.cx = PlatformInvokeUSER32.GetSystemMetrics
                  (PlatformInvokeUSER32.SM_CXSCREEN);

        //Мы передаем SM_CYSCREEN константа GetSystemMetrics и получить Y координаты экрана.
        size.cy = PlatformInvokeUSER32.GetSystemMetrics
                  (PlatformInvokeUSER32.SM_CYSCREEN);

        //Мы создаем совместимое растровое изображение экрана с размером с помощью
        //контекст устройства экрана.
        hBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap
                    (hDC, size.cx, size.cy);

        //Как hBitmap IntPtr, мы не можем проверить его значение null.
        //Для этой цели используется значение IntPtr.Zero.
        if (hBitmap != IntPtr.Zero)
        {
            //Здесь мы выбираем совместимое растровое изображение в памяти устройства
            //контекст и держит ссылку на старый битовый массив.
            IntPtr hOld = (IntPtr)PlatformInvokeGDI32.SelectObject
                                   (hMemDC, hBitmap);
            //Мы копируем Битовый массив к контексту устройства памяти.
            PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC,
                                       0, 0, PlatformInvokeGDI32.SRCCOPY);
            //Мы выбираем старый битовый массив назад к контексту устройства памяти.
            PlatformInvokeGDI32.SelectObject(hMemDC, hOld);
            //Мы удаляем контекст устройства памяти.
            PlatformInvokeGDI32.DeleteDC(hMemDC);
            //Мы выпускаем контекст устройства экрана.
            PlatformInvokeUSER32.ReleaseDC(PlatformInvokeUSER32.
                                           GetDesktopWindow(), hDC);
            //Изображение создано и сохранено в локальную переменную
           
            Bitmap bmp = System.Drawing.Image.FromHbitmap(hBitmap);
            //Освободим память, чтобы избежать утечек памяти.
            PlatformInvokeGDI32.DeleteObject(hBitmap);
            //Вызовим сборщик мусора.
            GC.Collect();
            //Вернем изображение
            return bmp;
        }
        //Если hBitmap пустой, возвратите пустой указатель.
        return null;
    }

}

//Эта структура должна использоваться, чтобы держать размер экрана.
public struct SIZE
{
    public int cx;
    public int cy;
}

Часть кода за комментирована, но этот пример мне не очень нравиться, он использует winapi и слишком большой. Лично мне нравиться больше второй вариант:


using System.Drawing;
using System.Windows.Forms;

public class Program
{
    public static void Main()
    {
            Bitmap printscreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
            Graphics graphics = Graphics.FromImage(printscreen as Image);
            graphics.CopyFromScreen(0, 0, 0, 0, printscreen.Size);
            printscreen.Save("D:\\1.jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);
    }
}

Обратите внимание на то что необходимо подключить ссылки на библиотеки Windows.Forms, а в первом случаи достаточно только Drawing.

Вот и все! Достаточно простые примеры которые вы сможете использовать в своих приложениях, по захвату изображения экрана и делать скриншоты.


Обновлено: 29.12.2018 — 11:45

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.