Сегодня пришло письмо, где человек спрашивал о том, можно ли сделать скриншот средствами PowerShell. Я вообще не очень понял зачем это, но это уже не моё дело. Если я пишу этот пост, значит можно :)

Для этого существует класс Drawing.Graphics у которого есть замечательный метод CopyFromScreen(). Данный метод принимает в качестве аргументов различные параметры, которые определяют координаты области, которую нужно сфоткать. В принципе можно забивать фиксированные значения (см. конструкторы с Int, как этот — CopyFromScreen(Int32, Int32, Int32, Int32, Size)), а можно эти размеры выставлять динамически, в зависимости от размеров экрана. Для этого лучше воспользоваться самым первым методом: CopyFromScreen(Point, Point, Size).

Как получить размеры экрана? Очень просто, достаточно воспользоваться статическим свойством VirtualScreen класса Windows.Forms.SystemInformation:

[Windows.Forms.SystemInformation]::VirtualScreen

[↓] [vPodans] [Windows.Forms.SystemInformation]::VirtualScreen Location : {X=0,Y=0} Size : {Width=1280, Height=800} X : 0 Y : 0 Width : 1280 Height : 800 Left : 0 Top : 0 Right : 1280 Bottom : 800 IsEmpty : False [↓] [vPodans]

Вот размеры экрана на моём нотебуке. Готично. Теперь нужно создать объект Drawing.Graphics. Однако, этот объект нельзя создать через New-Object, поскольку для этого нет ни одного конструктора. Следовательно объект нужно создавать используя статические методы. Статические методы можно посмотреть на странице Drawing.Graphics Members. И там мы можем найти красивый метод — FromImage. В качестве аргумента этого метода нужно указать картинку — http://msdn.microsoft.com/en-us/library/system.drawing.image.aspx. Это может быть файл или объект класса Drawing.Bitmap. Давайте создадим объект класса Drawing.Bitmap с использованием следующего конструктора — Bitmap Constructor (Int32, Int32):

[↓] [vPodans] [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") [↓] [vPodans] $size = [Windows.Forms.SystemInformation]::VirtualScreen [↓] [vPodans] $bitmap = new-object Drawing.Bitmap $size.width, $size.height [↓] [vPodans] $bitmap Tag : PhysicalDimension : {Width=1280, Height=800} Size : {Width=1280, Height=800} Width : 1280 Height : 800 HorizontalResolution : 96 VerticalResolution : 96 Flags : 2 RawFormat : [ImageFormat: b96b3caa-0728-11d3-9d7b-0000f81ef32e] PixelFormat : Format32bppArgb Palette : System.Drawing.Imaging.ColorPalette FrameDimensionsList : {7462dc86-6180-4c7e-8e3f-ee7333a7a483} PropertyIdList : {} PropertyItems : {} [↓] [vPodans]

Примечание: WinForms по умолчанию не загружаются вместе с PowerShell, поэтому мы их подгружаем в консоль в ходе работы. Мы создали Bitmap и теперь его можем использовать для создания объекта Drawing.Graphics:

$graphics = [Drawing.Graphics]::FromImage($bitmap)

А дальше уже вызывать метод CopyFromScreen(). При этом указываем первым аргументом начало координат (верхний левый угол или 0,0) и в аргумент правый нижний угол. Т.е. максимум точек по ширине и высоте. Их мы можем получить из свойств Width и Height класса Windows.Forms.SystemInformation. Средний аргумент опускаем и делаем его пустым:

[↓] [vPodans] $graphics = [Drawing.Graphics]::FromImage($bitmap) [↓] [vPodans] $graphics.CopyFromScreen($size.Location,[Drawing.Point]::Empty, $size.size)

Всё, мы сфоткали наш экран и загнали картинку обратно в Bitmap. Теперь нужно выгрузить картинку куда-то в файл. Для этого у Bitmap есть метод Save(), в котором достаточно указать путь к файлу:

[↓] [vPodans] $bitmap.save(".\screenshot.jpg") [↓] [vPodans] gi .\screenshot.jpg Directory: C:\Users\vPodans Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 22.04.2010 22:37 286319 screenshot.jpg [↓] [vPodans]

Всё :)

Примечание: после сохранения картинка остаётся в памяти, поэтому после работы следует освобождать оперативную память от ненужных пруфпиков используя метод Dispose() без аргументов.

И код:

[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$size = [Windows.Forms.SystemInformation]::VirtualScreen
$bitmap = new-object Drawing.Bitmap $size.width, $size.height
$graphics = [Drawing.Graphics]::FromImage($bitmap)
$graphics.CopyFromScreen($size.location,[Drawing.Point]::Empty, $size.size)
$graphics.Dispose()
$bitmap.Save(".\screenshot.jpg")
$bitmap.Dispose()
Thursday, April 22, 2010 11:43:41 PM (FLE Daylight Time, UTC+03:00)   Comments [4]    

 

Friday, April 23, 2010 7:14:37 AM (FLE Daylight Time, UTC+03:00)
Пользуясь тем что начал снова понимать твой код, несколько мелких придирочек: :)
>достаточно воспользоваться статическим методом VirtualScreen класса Windows.Forms.SystemInformation
Это статическое свойство скорее.

>WinForms по умолчанию не загружаются вместе с PowerShell
Зависит от. Точно загружаются в ISE, да вроде и в простом v2.0 всегда есть в наличии при старте.

>после сохранения картинка остаётся в памяти, поэтому после работы следует освобождать оперативную память от ненужных пруфпиков используя метод Dispose() без аргументов
Если совсем придираться к словам - Dispose() помечает объект для удаления из памяти. А память освободится тогда когда кто нибудь будет поджимать, при следующем регулярном вызове Garbage Collector'а, или если вызвать его вручную: [gc]::Collect()

>Домашния страница
В форме отправки комментария опечатка :)
Friday, April 23, 2010 12:34:05 PM (FLE Daylight Time, UTC+03:00)
> Это статическое свойство скорее.
угу. Там же скобок нету.

> Зависит от. Точно загружаются в ISE, да вроде и в простом v2.0 всегда есть в наличии при старте.
а этот код работает и в 1.0 тоже, где WinForms нет по дефолту.

>Если совсем придираться к словам - Dispose() помечает объект для удаления из памяти.
ну на MSDN написано, что этот метод освобождает ресурсы. Я не в курсе, как там точно происходит.

> В форме отправки комментария опечатка :)
знаю. И с этим ничего поделать не могу. Разве что убрать русску локализацию интерфейса, что я, наверное, и сделаю.
Monday, April 26, 2010 9:54:47 AM (FLE Daylight Time, UTC+03:00)
Приветы.

Я бы заменил название переменной $size на, например, $Screen или $ScreenArea. А то, $size.size выглядит как-то не совсем православно и режет глаз ;)
Monday, April 26, 2010 10:01:24 AM (FLE Daylight Time, UTC+03:00)
Я не думаю, что это уж очень критично :)
OpenID
Please login with either your OpenID above, or your details below.
Name
E-mail
(will show your gravatar icon)
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Live Comment Preview
 · 

All content © 2008 - 2012, Vadims Podāns
"Spaces" Theme provided by: Vadims Podāns
About


E-mail - Send mail to the author(s)
Live Messenger -
For english language visitors
Библиотека
Календарик
<February 2012>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

Карта расположения посетителей
Favorites





Fan list



Disclaimer
Вся информация на сайте предоставляется на условиях «как есть», без предоставления каких-либо гарантий и прав.

При использовании материалов c данного сайта ссылка на оригинальный источник обязательна.
Protected by Copyscape Online Plagiarism Scanner