• Home
  • blog
  • photos
  • projects
  • about
Menu
  • Home
  • blog
  • photos
  • projects
  • about
August 27, 2009

C# – Захват содержимого экрана (.net 2.0)

Бывает много ситуаций, когда необходимо сделать снимок экрана, на пример при поддержке установленного программного обеспечения снимок экрана может очень сильно помочь в описании проблемы.

В этой статье мы рассмотрим как сделать снимок экрана, отобразить его, а так же сохранить на диск.

В далекие времена .NET Framework 1.0, что бы сделать снимок экрана приходилось прибегать к вызову Windows API. В .NET Framework 2.0 в пространстве имен System.Drawing и System.Drawing.Imaging появляются новые классы, которые, благодаря GDI+, позволяют работать с графикой, используя только .NET.

Для демонстрации создадим простую Windows Forms программу, которая будет получать снимок экрана, отображать его на форме, а так же при необходимости сохранять его в виде графического файла.

Разместим на форме 4-е кнопки с именами btnCapture, btnSaveJpg, btnSavePng, btnClose, один PictureBox с именем img, а так же SaveFileDialog с именем dlg.

Перейдем к коду, нам потребуется подключить пространства имен

System.Drawing и System.Drawing.Imaging.
 
using System.Drawing;
using System.Drawing.Imaging;

Теперь нам понадобится объект Bitmap (растровое изображение), который будет использоваться для хранения снимка экрана, но т.к. он будет нужен как при самом получении изображения, так и при сохранении изображения, то лучше его сделать частью класса frmMain.

public partial class frmMain : Form
{
    private Bitmap captured;
 
    public frmMain()
    {
        InitializeComponent();
    }
...

Далее создадим процедуру получения снимка экрана по нажатию на кнопку btnCapture. Во первых необходимо определить размер создаваемого изображения, а так же глубину цвета. Эти данные можно получить из свойств объекта Screen. В примере будет использоваться основной экран, что для варианта с одним монитором вполне годится, а в случае с несколькими мониторами необходимо использовать массив Screen.AllScreens[].

Размер изображения:

Rectangle bounds = Screen.PrimaryScreen.Bounds;

Глубина цвета – это количество бит, выделяемых на каждую точку на экране, что в свою очередь определяет количество цветов, которое может принимать эта точка. Для минимизировать использование памяти будем использовать полученное значение для создания растрового изображения:

int colourDepth = Screen.PrimaryScreen.BitsPerPixel;

Что бы использовать полученное значение глубины цвета, необходимо создать объект RixelFormat, который представляет из себя перечисление и присвоить ему соответствующее значение. Существует некоторое ограничение для значения в 8-мь бит, по этому для таких снимков экрана будет создаваться 16-и битное изображение.

PixelFormat format;
switch (colourDepth)
{
    case 8:
    case 16:
        format = PixelFormat.Format16bppRgb565;
        break;
 
    case 24:
        format = PixelFormat.Format24bppRgb;
        break;
 
    case 32:
        format = PixelFormat.Format32bppArgb;
        break;
 
    default:
        format = PixelFormat.Format32bppArgb;
        break;
 
}

Теперь, зная значение глубины цвета и размера изображения, можно инициализировать объект bitmap, которому ранее было присвоено имя captured:

captured = new Bitmap(bounds.Width, bounds.Height, format);

Переходим к использованию GDI+, создадим поверхность для рисования, которая будет связана с нашим растровым изображением.

Graphics gdi = Graphics.FromImage(captured);

Ну и наконец сделаем снимок экрана, в этом нам поможет метод CopyFromScreen, в него передаются 5-ть параметров, первые два это координаты левого верхнего пикселя копируемого изображения, следующие два это координаты места вставки изображения в “холст” GDI+, последний параметр это размер копируемой области.

gdi.CopyFromScreen(bounds.Left, bounds.Top, 0, 0, bounds.Size);

Ну а теперь можно вывести полученное изображение в PictureBox на нашей форме:

img.BackgroundImageLayout = ImageLayout.Zoom;
img.BackgroundImage = captured;

Вся процедура обработки нажатия на кнопку btnCapture:

private void btnCapture_Click(object sender, EventArgs e)
{
     Rectangle bounds = Screen.PrimaryScreen.Bounds;
     int colourDepth = Screen.PrimaryScreen.BitsPerPixel;
     PixelFormat format;
     switch (colourDepth)
     {
          case 8:
          case 16:
              format = PixelFormat.Format16bppRgb565;
              break;
 
          case 24:
              format = PixelFormat.Format24bppRgb;
              break;
 
          case 32:
              format = PixelFormat.Format32bppArgb;
              break;
 
          default:
              format = PixelFormat.Format32bppArgb;
              break;
     }
     captured = new Bitmap(bounds.Width, bounds.Height, format);
     Graphics gdi = Graphics.FromImage(captured);
     gdi.CopyFromScreen(bounds.Left, bounds.Top, 0, 0, bounds.Size);
     img.BackgroundImageLayout = ImageLayout.Zoom;
     img.BackgroundImage = captured;
}

Теперь создадим процедуры сохранения полученного изображения в файл. Сохранение в формате jpeg при нажатии на кнопке btnSaveJpg. Проверяем инициализирован ли объект bitmap, если да, то открываем диалоговое окно сохранения файла в котором настроен фильтр на отображение только изображений в формате jpeg, если файл выбран, то сохраняем, используя метод Save объекта Bitmap.

private void btnSaveJpg_Click(object sender, EventArgs e)
{
     if (captured != null)
     {
          dlg.Filter = "Jpeg image|*.jpg|All files|*.*";
          dlg.Title = "Save captured screen as jpeg";
          if (dlg.ShowDialog() == DialogResult.OK)
          {
               captured.Save(dlg.FileName, ImageFormat.Jpeg);
          }
     }
}

Сохранение в формате png при нажатии на кнопке btnSavePng.

private void btnSavePng_Click(object sender, EventArgs e)
{
     if (captured != null)
     {
          dlg.Filter = "PNG image|*.png|All files|*.*";
          dlg.Title = "Save captured screen as png";
          if (dlg.ShowDialog() == DialogResult.OK)
          {
              captured.Save(dlg.FileName, ImageFormat.Png);
          }
     }
}

Вот и все.

Разработка
/
csharp,howto
/
August 27, 2009
/
3 Comments
Previous MiktoTik – Два провайдера – распределение по каналам Next MikroTik – Winbox vs Console

3 Replies to “C# – Захват содержимого экрана (.net 2.0)”

  1. arxont says:
    October 3, 2010 at 16:13

    Спасибо за пример, я ещё добавил чтобы окно при снятии сворачивалось.

    Reply
  2. Анонимный says:
    March 22, 2011 at 16:13

    Сергей, напишите статью, как сделать скриншот с приложений использующих directx(на c#).
    Поскольку этим методом, я так понимаю, сохранится, лишь черный экран.
    если можете, оповестите меня в случае написания данной статьи. dan-ver@ukr.net

    Reply
  3. Юрий says:
    February 5, 2017 at 16:14

    Наверно не
    captured = new Bitmap(bounds.Width, bounds.Height, format);
    а
    Bitmap captured = new Bitmap(bounds.Width, bounds.Height, format);

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Notepads

  • Админево
  • Разработка
  • Фотография
  • Электроника
  • Разное
Menu
  • Админево
  • Разработка
  • Фотография
  • Электроника
  • Разное

Tags

Tags
antiquities (6) aquarium (1) csharp (1) dos (6) hardware (1) howto (16) linux (1) mikrotik (14) ms sql (2) netflow (1) norton commander (2) powershell (1) router os (14) sql (2) virtualbox (6) windows (2) wsus (2) мудрость (1)

Links

  •   i’m on facebook
  •   my photos on flickr
  •   my code on github
  •   write me email
  •   headhunt me
Menu
  •   i’m on facebook
  •   my photos on flickr
  •   my code on github
  •   write me email
  •   headhunt me
Яндекс.Метрика

Sergey Lagovskiy © 2009-2021 Οδύσσεια 0.6