Некоторое время назад мне понадобился инструмент, с помощью которого я смог бы программно создавать снимки с целого экрана монитора или с некоторой его области. При этом необходима возможность указания области не только программно, но и вручную пользователем с помощью мыши. Полученный результат должен быть сразу же упакован в экземпляр одного из классов, которые мне было бы удобно использовать для отображения полученного скрина в GUI (графическом интерфейсе пользователя):
Моё решение о том, в объекты каких классов должен быть упакован конечный результат обусловлен удобством их (классов) использования в WPF:
Класс System.Drawing.Bitmap содержит метод Save, позволяющий записать полученный снимок в растровый файл изображения (указав при этом файл какого типа следует создать).
Класс System.Windows.Media.Imaging.BitmapImage часто используется в качестве источника данных для System.Windows.Controls.Image, используемого в WPF для отображения растровых изображений.
Класс System.IO.MemoryStream понадобился мне в для того, чтобы можно было сохранить изображение в таблицу базы данных, хотя, конечно же, это далеко не единственный случай, в котором может понадобиться представленное в таком виде изображение.
Поискав в Google готовое решение и не найдя то, что полностью соответствовало бы моему желанию — сел за написание своей библиотеки. Необходимый мне функционал я решил реализовать в виде методов статического класса. Классу присваиваю имя ScreenManager. В нём должны быть реализованы следующие методы:
Конечный результат должен быть представлен в виде dll-библиотеки с xml-файлом, содержащим информацию о ней.
Класс ScreenManager делаю частичным, дабы распределить код по разным cs-файлам в соответствии с логикой выполняемых ими действий. Таких файлов у меня будет три:
Файл ProgramMethods.cs будет содержать в себе те методы, которые позволят получать снимки всего экрана или его области в прозрачном режиме, не требуя от пользователя указания границ области вручную.
Файл ManuallyMethods.cs наоборот должен будет инкапсулировать в себе методы, которые будут запрашивать у пользователя указание области экрана, с которой следует делать снимок. Пользователь должен будет нажать левую кнопку мыши, указав тем самым первый угол области и не отпуская кнопки указать противоположный по диагонали угол, отпустив на нём нажатую кнопку. В процессе перемещения указателя мыши на экране область выбираемой границы должна быть обозначена прямоугольником некоторого цвета, динамически изменяющим свои размеры в процессе перемещения мыши по экрану монитора. Если в процессе выбора области пользователь нажмёт клавишу Escape — команда получения снимка должна быть прервана. Цвет прямоугольника и толщина линий должны быть настраиваемы через статические свойства RectangleBrush и RectangleLineWeigth класса ScreenManager.
Файл InnerMethods.cs будет содержать в себе набор вспомогательных методов, необходимых для работы кода файла ManuallyMethods.cs.
После того, как код библиотеки будет полностью написан — нужно будет создать тестовое приложение (назовём его «WPF test»), демонстрирующее работу библиотеки. Это будет маленькое WPF окошко, с объектом Image и Button, достаточных для требующейся демонстрации.
Ну вот, собственно и всё… Далее приводится исходный код cs-файлов, упомянутых мною выше:
Файл ProgramMethods.cs
Файл ManuallyMethods.cs
Файл InnerMethods.cs
Далее представлен код тестового приложения WpfTest:
Файл Window1.xaml
Файл Window1.xaml.cs
Результат работы тестового приложения выглядит так (полученный результат отображается в окошке «ScreenManager testing»):
Код написан с использованием MS Visual Studio 2008 SP1 и .Net Framework 3.5 SP1.
Исходный код проекта находится здесь.
Release версия библиотеки здесь.
- System.Drawing.Bitmap
- System.Windows.Media.Imaging.BitmapImage
- System.IO.MemoryStream
Моё решение о том, в объекты каких классов должен быть упакован конечный результат обусловлен удобством их (классов) использования в WPF:
Класс System.Drawing.Bitmap содержит метод Save, позволяющий записать полученный снимок в растровый файл изображения (указав при этом файл какого типа следует создать).
Класс System.Windows.Media.Imaging.BitmapImage часто используется в качестве источника данных для System.Windows.Controls.Image, используемого в WPF для отображения растровых изображений.
Класс System.IO.MemoryStream понадобился мне в для того, чтобы можно было сохранить изображение в таблицу базы данных, хотя, конечно же, это далеко не единственный случай, в котором может понадобиться представленное в таком виде изображение.
Поискав в Google готовое решение и не найдя то, что полностью соответствовало бы моему желанию — сел за написание своей библиотеки. Необходимый мне функционал я решил реализовать в виде методов статического класса. Классу присваиваю имя ScreenManager. В нём должны быть реализованы следующие методы:
Конечный результат должен быть представлен в виде dll-библиотеки с xml-файлом, содержащим информацию о ней.
Класс ScreenManager делаю частичным, дабы распределить код по разным cs-файлам в соответствии с логикой выполняемых ими действий. Таких файлов у меня будет три:
- ProgramMethods.cs
- ManuallyMethods.cs
- InnerMethods.cs
Файл ProgramMethods.cs будет содержать в себе те методы, которые позволят получать снимки всего экрана или его области в прозрачном режиме, не требуя от пользователя указания границ области вручную.
Файл ManuallyMethods.cs наоборот должен будет инкапсулировать в себе методы, которые будут запрашивать у пользователя указание области экрана, с которой следует делать снимок. Пользователь должен будет нажать левую кнопку мыши, указав тем самым первый угол области и не отпуская кнопки указать противоположный по диагонали угол, отпустив на нём нажатую кнопку. В процессе перемещения указателя мыши на экране область выбираемой границы должна быть обозначена прямоугольником некоторого цвета, динамически изменяющим свои размеры в процессе перемещения мыши по экрану монитора. Если в процессе выбора области пользователь нажмёт клавишу Escape — команда получения снимка должна быть прервана. Цвет прямоугольника и толщина линий должны быть настраиваемы через статические свойства RectangleBrush и RectangleLineWeigth класса ScreenManager.
Файл InnerMethods.cs будет содержать в себе набор вспомогательных методов, необходимых для работы кода файла ManuallyMethods.cs.
После того, как код библиотеки будет полностью написан — нужно будет создать тестовое приложение (назовём его «WPF test»), демонстрирующее работу библиотеки. Это будет маленькое WPF окошко, с объектом Image и Button, достаточных для требующейся демонстрации.
Ну вот, собственно и всё… Далее приводится исходный код cs-файлов, упомянутых мною выше:
Файл ProgramMethods.cs
1: using System;<br> 2: using System.Collections.Generic;<br> 3: using System.Linq;<br> 4: using System.Text;<br> 5: using System.Windows.Forms;<br> 6: using System.Drawing;<br> 7: using System.Drawing.Imaging;<br> 8: using System.Windows.Media.Imaging;<br> 9: using System.IO;<br> 10: using System.Windows.Shapes;<br> 11: using System.Windows.Controls;<br> 12: using System.Windows.Input;<br> 13: using System.Windows;<br> 14: <br> 15: namespace Bushman.Screens<br> 16: {<br> 17: /// <summary><br> 18: /// Данный статический класс предназначен для получения скринов с экрана монитора с последующей упаковкой результата в<br> 19: /// различные объекты<br> 20: /// </summary><br> 21: public static partial class ScreenManager<br> 22: {<br> 23: //В данном файле частичного класса находятся методы, с помощью которых скрины создаются программно (т.е. без использования мыши).<br> 24: /// <summary><br> 25: /// Получение скрина, упакованного в объект BitmapImage. Скрин снимается с заданной прямоугольной области экрана.<br> 26: /// </summary><br> 27: /// <param name="rect">Объект System.Drawing.Rectangle, указывающий место расположения и размеры прямоугольной области,<br> 28: /// для которой следует сделать снимок</param><br> 29: /// <param name="format">Формат графического файла, который должен быть упакован в поток</param><br> 30: /// <returns>Возвращается изображение, упакованное в объект класса BitmapImage</returns><br> 31: public static BitmapImage GetBitmapImageFromScreen(System.Drawing.Rectangle rect, ImageFormat format)<br> 32: {<br> 33: using (MemoryStream ms = new MemoryStream())<br> 34: {<br> 35: Screen screen = Screen.FromRectangle(rect);<br> 36: Bitmap bitmap = new Bitmap(rect.Width, rect.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); <br> 37: Graphics graphics = Graphics.FromImage(bitmap);<br> 38: graphics.CopyFromScreen(rect.X, rect.Y, 0, 0, rect.Size, CopyPixelOperation.SourceCopy); <br> 39: bitmap.Save(ms, format);<br> 40: BitmapImage img = new BitmapImage();<br> 41: img.BeginInit();<br> 42: img.CacheOption = BitmapCacheOption.OnLoad;<br> 43: img.StreamSource = ms;<br> 44: img.EndInit();<br> 45: return img;<br> 46: }<br> 47: }<br> 48: /// <summary><br> 49: /// Получение скрина, упакованного в объект BitmapImage. Скрин снимается со всей области экрана.<br> 50: /// </summary><br> 51: /// <returns>Возвращается изображение, упакованное в объект класса BitmapImage</returns><br> 52: public static BitmapImage GetBitmapImageFromScreen(ImageFormat format)<br> 53: {<br> 54: System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);<br> 55: return GetBitmapImageFromScreen(rect, format);<br> 56: }<br> 57: <br> 58: /// <summary><br> 59: /// Получение скрина, упакованного в объект MemoryStream. Скрин снимается с заданной прямоугольной области экрана.<br> 60: /// </summary><br> 61: /// <param name="rect">Объект System.Drawing.Rectangle, указывающий место расположения и размеры прямоугольной области,<br> 62: /// для которой следует сделать снимок</param><br> 63: /// <param name="format">Формат графического файла, который должен быть упакован в поток</param><br> 64: /// <returns>Возвращается изображение, упакованное в объект класса MemoryStream</returns><br> 65: public static MemoryStream GetMemoryStreamFromScreen(System.Drawing.Rectangle rect, ImageFormat format)<br> 66: {<br> 67: MemoryStream ms = new MemoryStream();<br> 68: Screen screen = Screen.FromRectangle(rect);<br> 69: Bitmap bitmap = new Bitmap(rect.Width, rect.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);<br> 70: Graphics graphics = Graphics.FromImage(bitmap);<br> 71: graphics.CopyFromScreen(rect.X, rect.Y, 0, 0, rect.Size, CopyPixelOperation.SourceCopy);<br> 72: bitmap.Save(ms, format);<br> 73: return ms;<br> 74: }<br> 75: <br> 76: /// <summary><br> 77: /// Получение скрина, упакованного в объект MemoryStream. Скрин снимается со всей области экрана.<br> 78: /// </summary><br> 79: /// <returns>Возвращается изображение, упакованное в объект класса MemoryStream</returns><br> 80: public static MemoryStream GetMemoryStreamFromScreen(ImageFormat format)<br> 81: {<br> 82: System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);<br> 83: return GetMemoryStreamFromScreen(rect, format);<br> 84: }<br> 85: <br> 86: /// <summary><br> 87: /// Получение скрина, упакованного в объект Bitmap. Скрин снимается с заданной прямоугольной области экрана.<br> 88: /// </summary><br> 89: /// <param name="rect">Объект System.Drawing.Rectangle, указывающий место расположения и размеры прямоугольной области,<br> 90: /// для которой следует сделать снимок</param><br> 91: /// <returns>Возвращается изображение, упакованное в объект класса Bitmap</returns><br> 92: public static Bitmap GetBitmapFromScreen(System.Drawing.Rectangle rect)<br> 93: {<br> 94: Screen screen = Screen.FromRectangle(rect);<br> 95: Bitmap bitmap = new Bitmap(rect.Width, rect.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);<br> 96: Graphics graphics = Graphics.FromImage(bitmap);<br> 97: graphics.CopyFromScreen(rect.X, rect.Y, 0, 0, rect.Size, CopyPixelOperation.SourceCopy); <br> 98: return bitmap;<br> 99: }<br> 100: <br> 101: /// <summary><br> 102: /// Получение скрина, упакованного в объект Bitmap. Скрин снимается со всей области экрана.<br> 103: /// </summary><br> 104: /// <returns>Возвращается изображение, упакованное в объект класса Bitmap</returns><br> 105: public static Bitmap GetBitmapFromScreen()<br> 106: {<br> 107: System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);<br> 108: return GetBitmapFromScreen(rect);<br> 109: }<br> 110: }<br> 111: }<br><br>* This source code was highlighted with Source Code Highlighter.
Файл ManuallyMethods.cs
1: using System;<br> 2: using System.Collections.Generic;<br> 3: using System.Linq;<br> 4: using System.Text;<br> 5: using System.Windows.Forms;<br> 6: using System.Drawing;<br> 7: using System.Drawing.Imaging;<br> 8: using System.Windows.Media.Imaging;<br> 9: using System.IO;<br> 10: using System.Windows.Shapes;<br> 11: using System.Windows.Controls;<br> 12: using System.Windows.Input;<br> 13: using System.Windows;<br> 14: <br> 15: namespace Bushman.Screens<br> 16: {<br> 17: //В этой части класса находятся методы, позволяющие указывать области снимаемого скрина вручную (мышью)<br> 18: public static partial class ScreenManager<br> 19: {<br> 20: //Далее представлены методы, позволяющие визуально (мышью) выбирать область на экране, с которой нужно сделать скрин<br> 21: //**************************************<br> 22: <br> 23: //Внутренние переменные, необходимые для решения задачи:<br> 24: static Window win;//Окно, содержащее в себе полный скрин экрана<br> 25: static System.Windows.Point firstPoint;//Первая точка границ скрина<br> 26: static System.Windows.Point secondPoint;//Вторая (противоположная по диагонали) точка границ скрина<br> 27: static Canvas canvas;<br> 28: static System.Windows.Controls.Image image;<br> 29: static List<Line> lines;//четыре линии, указывающие границы пользовательского выбора<br> 30: static ImageFormat format;<br> 31: static MemoryStream result;<br> 32: static System.Windows.Media.Brush rectangleBrush = System.Windows.Media.Brushes.Black;<br> 33: static double rectangleLineWeigth = 5;<br> 34: <br> 35: /// <summary><br> 36: /// Цвет линий прямоугольной области, выбираемой пользователем на экране вручную<br> 37: /// </summary><br> 38: public static System.Windows.Media.Brush RectangleBrush<br> 39: {<br> 40: get { return rectangleBrush; }<br> 41: set { rectangleBrush = value; }<br> 42: }<br> 43: /// <summary><br> 44: /// Толщина линий прямоугольной области, выбираемой пользователем на экране вручную<br> 45: /// </summary><br> 46: public static double RectangleLineWeigth<br> 47: {<br> 48: get { return rectangleLineWeigth; }<br> 49: set { rectangleLineWeigth = value; }<br> 50: }<br> 51: <br> 52: /// <summary><br> 53: /// Получение скрина области экрана, вручную указанную пользователем рамкой<br> 54: /// </summary><br> 55: /// <param name="imgFormat">Формат графического файла, который должен быть упакован в поток</param><br> 56: /// <returns>Возвращается экземпляр MemoryStream</returns><br> 57: public static MemoryStream GetMemoryStreamFromScreenManually(ImageFormat imgFormat)<br> 58: {<br> 59: format = imgFormat;<br> 60: //Создаю новое окно, которое заполняет собой всю область экрана<br> 61: win = new Window() { WindowState = WindowState.Maximized, WindowStyle = WindowStyle.None };<br> 62: <br> 63: //Получаю скрин всего экрана, упакованный в объект класса BitmapImage<br> 64: BitmapImage bitmapImage = ScreenManager.GetBitmapImageFromScreen(ImageFormat.Png);<br> 65: <br> 66: //Формирую содержимое окна<br> 67: image = new System.Windows.Controls.Image() { Source = bitmapImage };<br> 68: canvas = new Canvas() { Width = Screen.PrimaryScreen.Bounds.Width, Height = Screen.PrimaryScreen.Bounds.Height };<br> 69: canvas.Children.Add(image);<br> 70: Canvas.SetTop(image, 0);<br> 71: Canvas.SetLeft(image, 0);<br> 72: win.Content = canvas;<br> 73: <br> 74: //При нажатии левой кнопки мыши должна запоминаться первая точка<br> 75: image.MouseLeftButtonDown += new MouseButtonEventHandler(image_MouseLeftButtonDown);<br> 76: //При перемещении курсора мыши с нажатой левой кнопкой должен отображаться прямоугольник<br> 77: //пользовательского выбора<br> 78: image.MouseMove += new System.Windows.Input.MouseEventHandler(image_MouseMove);<br> 79: <br> 80: //================<br> 81: //************************************************************<br> 82: //================<br> 83: <br> 84: //При возврате левой кнопки мыши в состояние покоя, должна запоминаться 2-я точка, после чего<br> 85: //снимается скрин с укзанной области и закрывается окно, содержащее полный скрин экрана<br> 86: image.MouseLeftButtonUp += new MouseButtonEventHandler(image_MouseLeftButtonUp);<br> 87: //В случае нажатия клавиши Escape следует закрыть окно, содержащее полный скрин экрана, прервав команду получения скрина<br> 88: image.KeyDown += new System.Windows.Input.KeyEventHandler(image_KeyDown);<br> 89: //Отображаю окно на весь экран<br> 90: win.ShowDialog();<br> 91: return result;<br> 92: }<br> 93: <br> 94: /// <summary><br> 95: /// Получение скрина области экрана, вручную указанную пользователем рамкой<br> 96: /// </summary><br> 97: /// <param name="imgFormat">Формат графического файла, который должен быть упакован в поток</param><br> 98: /// <returns>Возвращается экземпляр Bitmap</returns><br> 99: public static Bitmap GetBitmapFromScreenManually(ImageFormat imgFormat)<br> 100: {<br> 101: MemoryStream ms = GetMemoryStreamFromScreenManually(imgFormat);<br> 102: return new Bitmap(ms);<br> 103: }<br> 104: <br> 105: /// <summary><br> 106: /// Получение скрина области экрана, вручную указанную пользователем рамкой<br> 107: /// </summary><br> 108: /// <param name="imgFormat">Формат графического файла, который должен быть упакован в поток</param><br> 109: /// <returns>Возвращается экземпляр BitmapImage</returns><br> 110: public static BitmapImage GetBitmapImageFromScreenManually(ImageFormat imgFormat)<br> 111: {<br> 112: MemoryStream ms = GetMemoryStreamFromScreenManually(imgFormat);<br> 113: BitmapImage bitmapImg = new BitmapImage();<br> 114: bitmapImg.BeginInit();<br> 115: bitmapImg.CacheOption = BitmapCacheOption.OnLoad;<br> 116: bitmapImg.StreamSource = ms;<br> 117: bitmapImg.EndInit();<br> 118: bitmapImg.Freeze();<br> 119: return bitmapImg;<br> 120: }<br> 121: }<br> 122: }<br><br>* This source code was highlighted with Source Code Highlighter.
Файл InnerMethods.cs
1: using System;<br> 2: using System.Collections.Generic;<br> 3: using System.Linq;<br> 4: using System.Text;<br> 5: using System.Windows.Forms;<br> 6: using System.Drawing;<br> 7: using System.Drawing.Imaging;<br> 8: using System.Windows.Media.Imaging;<br> 9: using System.IO;<br> 10: using System.Windows.Shapes;<br> 11: using System.Windows.Controls;<br> 12: using System.Windows.Input;<br> 13: using System.Windows;<br> 14: <br> 15: namespace Bushman.Screens<br> 16: {<br> 17: //В этой части класса находятся обработчики событий, происходящих при указании области снимаемого скрина вручную (мышью)<br> 18: public static partial class ScreenManager<br> 19: {<br> 20: static void image_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)<br> 21: {<br> 22: if (e.Key == Key.Escape) win.Close();<br> 23: }<br> 24: <br> 25: static void image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)<br> 26: {<br> 27: firstPoint = e.GetPosition(win);<br> 28: lines = new List<Line>();<br> 29: for (int i = 0; i < 4; i++)<br> 30: {<br> 31: Line item = new Line();<br> 32: item.Stroke = RectangleBrush;<br> 33: item.StrokeThickness = RectangleLineWeigth;<br> 34: canvas.Children.Add(item);<br> 35: Canvas.SetTop(item, firstPoint.Y);<br> 36: Canvas.SetLeft(item, firstPoint.X);<br> 37: item.StrokeEndLineCap = System.Windows.Media.PenLineCap.Round;<br> 38: item.StrokeStartLineCap = System.Windows.Media.PenLineCap.Round;<br> 39: item.Y2 = 0;<br> 40: item.X2 = 0;<br> 41: lines.Add(item);<br> 42: item.MouseLeftButtonUp += new MouseButtonEventHandler(image_MouseLeftButtonUp);<br> 43: item.KeyDown += new System.Windows.Input.KeyEventHandler(image_KeyDown);<br> 44: }<br> 45: }<br> 46: <br> 47: static void image_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)<br> 48: {<br> 49: if (e.LeftButton == MouseButtonState.Pressed)<br> 50: {<br> 51: lines[0].Y2 = e.GetPosition(win).Y - firstPoint.Y;<br> 52: <br> 53: lines[1].X2 = e.GetPosition(win).X - firstPoint.X;<br> 54: <br> 55: lines[2].Y1 = lines[0].Y2;<br> 56: lines[2].Y2 = lines[2].Y1;<br> 57: lines[2].X2 = lines[1].X2;<br> 58: <br> 59: lines[3].X1 = lines[1].X2;<br> 60: lines[3].X2 = lines[3].X1;<br> 61: lines[3].Y2 = lines[0].Y2;<br> 62: }<br> 63: }<br> 64: <br> 65: static void image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)<br> 66: {<br> 67: GetSecondPoint(e.GetPosition(win));<br> 68: }<br> 69: <br> 70: static void GetSecondPoint(System.Windows.Point point)<br> 71: {<br> 72: foreach (Line line in lines)<br> 73: {<br> 74: canvas.Children.Remove(line);<br> 75: }<br> 76: secondPoint = point;<br> 77: int top = (int)Math.Min(firstPoint.Y, secondPoint.Y);<br> 78: int left = (int)Math.Min(firstPoint.X, secondPoint.X);<br> 79: int height = (int)(Math.Max(firstPoint.Y, secondPoint.Y) - Math.Min(firstPoint.Y, secondPoint.Y));<br> 80: int width = (int)(Math.Max(firstPoint.X, secondPoint.X) - Math.Min(firstPoint.X, secondPoint.X));<br> 81: <br> 82: //Создаю прямоугольник, указывающий область на экране, с которой следует делать скрин<br> 83: System.Drawing.Rectangle rect = new System.Drawing.Rectangle(left, top, width, height);<br> 84: result = ScreenManager.GetMemoryStreamFromScreen(rect, format);<br> 85: //Закрываю окно<br> 86: win.Close();<br> 87: }<br> 88: //**************************************<br> 89: }<br> 90: }<br><br>* This source code was highlighted with Source Code Highlighter.
Далее представлен код тестового приложения WpfTest:
Файл Window1.xaml
1: <Window x:Class="WpfTest.Window1"<br> 2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"<br> 3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"<br> 4: Title="ScreenManager testing" Height="300" Width="300"><br> 5: <Grid><br> 6: <Grid.RowDefinitions><br> 7: <RowDefinition Height="100*" /><br> 8: <RowDefinition Height="Auto" /><br> 9: </Grid.RowDefinitions><br> 10: <Image Name="img" HorizontalAlignment="Center"></Image><br> 11: <StackPanel Name="stack" Grid.Row="1"><br> 12: <Button Name="btnSaveScreen">Save screen (manually method)</Button><br> 13: </StackPanel> <br> 14: </Grid><br> 15: </Window><br><br>* This source code was highlighted with Source Code Highlighter.
Файл Window1.xaml.cs
1: using System;<br> 2: using System.Collections.Generic;<br> 3: using System.Linq;<br> 4: using System.Text;<br> 5: using System.Windows;<br> 6: using System.Windows.Controls;<br> 7: using System.Windows.Data;<br> 8: using System.Windows.Documents;<br> 9: using System.Windows.Input;<br> 10: using System.Windows.Media;<br> 11: using System.Windows.Media.Imaging;<br> 12: using System.Windows.Navigation;<br> 13: using System.Windows.Shapes;<br> 14: using System.Drawing.Imaging;<br> 15: using System.Drawing;<br> 16: using Bushman.Screens;<br> 17: using System.IO;<br> 18: <br> 19: namespace WpfTest<br> 20: {<br> 21: /// <summary><br> 22: /// Interaction logic for Window1.xaml<br> 23: /// </summary><br> 24: public partial class Window1 : Window<br> 25: {<br> 26: public Window1()<br> 27: {<br> 28: InitializeComponent();<br> 29: MyInitialize();<br> 30: }<br> 31: void MyInitialize()<br> 32: {<br> 33: btnSaveScreen.Click += new RoutedEventHandler(btnSaveScreenManually_Click);<br> 34: }<br> 35: <br> 36: void btnSaveScreenManually_Click(object sender, RoutedEventArgs e)<br> 37: {<br> 38: string dirName = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "ScreenResults");<br> 39: DirectoryInfo dir = new DirectoryInfo(dirName);<br> 40: if (!dir.Exists) dir = Directory.CreateDirectory(dirName);<br> 41: System.Drawing.Rectangle rect = new System.Drawing.Rectangle(50, 50, 300, 200);<br> 42: Bitmap bitmap;<br> 43: MemoryStream ms;<br> 44: <br> 45: ///Ниже закомментированы примеры использования всех методов, извлекающих снимки с экрана. Раскомментируйте вариант, <br> 46: ///интересующий вас и запустите данное приложение на исполнение.<br> 47: <br> 48: //Вариант 1<br> 49: //bitmap = ScreenManager.GetBitmapFromScreen();<br> 50: //bitmap.Save(System.IO.Path.Combine(dir.FullName, "GetBitmapFromScreen_0.png"));<br> 51: //bitmap.Dispose();<br> 52: <br> 53: //Вариант 2<br> 54: //bitmap = ScreenManager.GetBitmapFromScreen(rect);<br> 55: //bitmap.Save(System.IO.Path.Combine(dir.FullName, "GetBitmapFromScreen_1.png"));<br> 56: //bitmap.Dispose();<br> 57: <br> 58: //Вариант 3<br> 59: //bitmap = ScreenManager.GetBitmapFromScreenManually(ImageFormat.Png);<br> 60: //bitmap.Save(System.IO.Path.Combine(dir.FullName, "GetBitmapFromScreenManually.png"));<br> 61: //bitmap.Dispose();<br> 62: <br> 63: //Вариант 4<br> 64: //img.Source = ScreenManager.GetBitmapImageFromScreen(ImageFormat.Png);<br> 65: <br> 66: //Вариант 5<br> 67: //img.Source = ScreenManager.GetBitmapImageFromScreen(rect, ImageFormat.Png);<br> 68: <br> 69: //Вариант 6<br> 70: img.Source = ScreenManager.GetBitmapImageFromScreenManually(ImageFormat.Png);<br> 71: <br> 72: //Вариант 7<br> 73: //ms = ScreenManager.GetMemoryStreamFromScreen(ImageFormat.Png);<br> 74: //bitmap = new Bitmap(ms);<br> 75: //bitmap.Save(System.IO.Path.Combine(dir.FullName, "GetMemoryStreamFromScreen_0.png"));<br> 76: //bitmap.Dispose();<br> 77: <br> 78: //Вариант 8<br> 79: //ms = ScreenManager.GetMemoryStreamFromScreen(rect, ImageFormat.Png);<br> 80: //bitmap = new Bitmap(ms);<br> 81: //bitmap.Save(System.IO.Path.Combine(dir.FullName, "GetMemoryStreamFromScreen_1.png"));<br> 82: //bitmap.Dispose();<br> 83: <br> 84: //Вариант 9<br> 85: //ms = ScreenManager.GetMemoryStreamFromScreenManually(ImageFormat.Png);<br> 86: //bitmap = new Bitmap(ms);<br> 87: //bitmap.Save(System.IO.Path.Combine(dir.FullName, "GetMemoryStreamFromScreenManually.png"));<br> 88: //bitmap.Dispose();<br> 89: }<br> 90: }<br> 91: }<br><br>* This source code was highlighted with Source Code Highlighter.
Результат работы тестового приложения выглядит так (полученный результат отображается в окошке «ScreenManager testing»):
Код написан с использованием MS Visual Studio 2008 SP1 и .Net Framework 3.5 SP1.
Исходный код проекта находится здесь.
Release версия библиотеки здесь.