windows-ss
Version:
[](https://badge.fury.io/js/windows-ss)
480 lines (283 loc) • 15.7 kB
Markdown
# windows-ss
[](https://badge.fury.io/js/windows-ss)
Take screenshots quickly on Windows by communicating directly with native API's.
> Did I mention that it's DPI aware too?
## Benchmark
Using [this repo](https://github.com/sxxov/windows-ss-benchmark). The numbers below were taken over 1000 runs, each at 2560x1440<sup>\*</sup>, outputing `bmp`.
| Library | Save to buffer | Save to file |
| ------------------ | -------------- | ------------ |
| windows-ss | **52ms** | **51ms** |
| screenshot-desktop | 152ms | 141ms |
| desktop-screenshot | n/a | 63ms<sup>\*\*</sup> |
<sup>\*</sup> Except for `desktop-screenshot`, it ran at 1706x960 as it's DPI unaware.
<sup>\*\*</sup> Times are relative to lower resolution of 1706x960. If interpolated back to 1440p according to a DPI of 1.5, `63 * (1.5 ^ 2) = 141ms`
## Installation
```bash
npm i windows-ss
```
> **IMPORTANT**: You'll need [.NET 4.5](http://www.microsoft.com/en-us/download/details.aspx?id=30653) or [.NET Core](https://www.microsoft.com/net/core) installed, as this library depends on `edge-js`. Refer [here](https://github.com/agracio/edge-js#scripting-clr-from-nodejs) for more info regarding installation.
## Usage
```ts
import { capturePrimaryMonitor } from 'windows-ss';
await capturePrimaryMonitor({
// The format of the returned Buffer & saved file.
format: 'png',
// How much to carve off the edges. (Left, Top, Right, Bottom)
crop: {
left: 0,
top: 0,
right: 0,
bottom: 0,
},
// The bounds where the screen will be captured. (Left, Top, Right, Bottom)
bounds: {
left: 0,
top: 0,
right: 0,
bottom: 0,
},
// The file the screenshot will be saved to.
save: './ss.png',
});
```
## API
### Table of Contents
* [Methods](#methods)
* <code>[getMonitorInfos](#getMonitorInfos)</code>
* <code>[getMonitorInfosSync](#getMonitorInfosSync)</code>
* <code>[captureMonitorByIndex](#captureMonitorByIndex)</code>
* <code>[captureMonitorByIndexSync](#captureMonitorByIndexSync)</code>
* <code>[captureMonitorByName](#captureMonitorByName)</code>
* <code>[captureMonitorByNameSync](#captureMonitorByNameSync)</code>
* <code>[captureWindowByTitle](#captureWindowByTitle)</code>
* <code>[captureWindowByTitleSync](#captureWindowByTitleSync)</code>
* <code>[captureActiveWindow](#captureActiveWindow)</code>
* <code>[captureActiveWindowSync](#captureActiveWindowSync)</code>
* [Interfaces](#interfaces)
* [`Configuration`](#configuration)
* [`MonitorInfo`](#monitorinfo)
* [`PlainRectangle`](#plainrectangle)
* [Errors](#errors)
* [`NoMatchError`](#NoMatchError)
* [`InvalidArgumentCountError`](#InvalidArgumentCountError)
* [`InvalidConfigurationError`](InvalidConfigurationError)
### Methods
#### `getMonitorInfos`
#### `getMonitorInfosSync`
Returns information about the the currently connected monitors.
##### Parameters
* n/a
##### Returns
* <code>Promise\<[MonitorInfo](#monitorinfo)[]\></code> —— <code>[MonitorInfo](#monitorinfo)[]</code>
* An array of [`MonitorInfo`](#monitorinfo)s gotten from the current system.
##### Throws
* n/a
##### Example
```ts
import { getMonitorInfos, getMonitorInfosSync } from 'windows-ss';
await getMonitorInfos();
getMonitorInfosSync();
/*
// Example output
[
{
monitor: { left: 0, top: 0, right: 2560, bottom: 1440 },
workArea: { left: 0, top: 0, right: 2560, bottom: 1380 },
deviceName: '\\\\.\\DISPLAY1'
},
{
monitor: { left: 304, top: -1080, right: 2224, bottom: 0 },
workArea: { left: 304, top: -1080, right: 2224, bottom: -40 },
deviceName: '\\\\.\\DISPLAY2'
}
]
*/
```
#### `captureMonitorByIndex`
#### `captureMonitorByIndexSync`
Captures a screenshot of the monitor matching the device index.
##### Parameters
* <code>deviceIndex: [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)</code>
* Index of monitor according to Windows.
* *(Optional)* <code>config: [Configuration](#configuration)</code>
* Additional options for capturing the screenshot.
##### Returns
* <code>Promise\<[Buffer](https://nodejs.org/api/buffer.html) | null\></code> —— <code>[Buffer](https://nodejs.org/api/buffer.html) | null</code>
* The binary image data of the screenshot, with the format specified in `options.format`. `null` is returned instead if `save` was passed into the `config` parameter.
##### Throws
* [`NoMatchError`](#nomatcherror)
* [`InvalidArgumentCountError`](#invalidargumentcounterror)
* [`InvalidConfigurationError`](#invalidconfigurationerror)
##### Example
```ts
import { captureMonitorByIndex, captureMonitorByIndexSync, getMonitorInfos } from 'windows-ss';
const monitorInfos = await getMonitorInfos();
await captureMonitorByIndex(monitorInfos.length - 1);
captureMonitorByIndexSync(0);
```
#### `captureMonitorByName`
#### `captureMonitorByNameSync`
Captures a screenshot of the monitor matching the device name.
##### Parameters
* <code>deviceName: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* Name of monitor according to Windows.
* *(Optional)* <code>config: [Configuration](#configuration)</code>
* Additional options for capturing the screenshot.
##### Returns
* <code>Promise\<[Buffer](https://nodejs.org/api/buffer.html) | null\></code> —— <code>[Buffer](https://nodejs.org/api/buffer.html) | null</code>
* The binary image data of the screenshot, with the format specified in `options.format`. `null` is returned instead if `save` was passed into the `config` parameter.
##### Throws
* [`NoMatchError`](#nomatcherror)
* [`InvalidArgumentCountError`](#invalidargumentcounterror)
* [`InvalidConfigurationError`](#invalidconfigurationerror)
##### Example
```ts
import { captureMonitorByName, captureMonitorByNameSync, getMonitorInfos } from 'windows-ss';
const monitorInfos = await getMonitorInfos();
await captureMonitorByName(monitorInfos[0].deviceName);
captureMonitorByNameSync(String.raw`\\.\DISPLAY1`);
```
#### `capturePrimaryMonitor`
#### `capturePrimaryMonitorSync`
Captures a screenshot of the primary monitor.
##### Parameters
* *(Optional)* <code>config: [Configuration](#configuration)</code>
* Additional options for capturing the screenshot.
##### Returns
* <code>Promise\<[Buffer](https://nodejs.org/api/buffer.html) | null\></code> —— <code>[Buffer](https://nodejs.org/api/buffer.html) | null</code>
* The binary image data of the screenshot, with the format specified in `options.format`. `null` is returned instead if `save` was passed into the `config` parameter.
##### Throws
* [`InvalidConfigurationError`](#invalidconfigurationerror)
##### Example
```ts
import { capturePrimaryMonitor, capturePrimaryMonitorSync } from 'windows-ss';
await capturePrimaryMonitor();
capturePrimaryMonitorSync();
```
#### `captureWindowByTitle`
#### `captureWindowByTitleSync`
Captures a screenshot of the window matching the title.
##### Parameters
* <code>title: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* Title of window.
* *(Optional)* <code>config: [Configuration](#configuration)</code>
* Additional options for capturing the screenshot.
##### Returns
* <code>Promise\<[Buffer](https://nodejs.org/api/buffer.html) | null\></code> —— <code>[Buffer](https://nodejs.org/api/buffer.html) | null</code>
* The binary image data of the screenshot, with the format specified in `options.format`. `null` is returned instead if `save` was passed into the `config` parameter.
##### Throws
* [`NoMatchError`](#nomatcherror)
* [`InvalidArgumentCountError`](#invalidargumentcounterror)
* [`InvalidConfigurationError`](#invalidconfigurationerror)
##### Example
```ts
import { captureWindowByTitle, captureWindowByTitleSync } from 'windows-ss';
await captureWindowByTitle('Task Manager');
captureWindowByTitleSync('Notepad');
```
#### `captureActiveWindow`
#### `captureActiveWindowSync`
Captures a screenshot of the currently active/focused window.
##### Parameters
* *(Optional)* <code>config: [Configuration](#configuration)</code>
* Additional options for capturing the screenshot.
##### Returns
* <code>Promise\<[Buffer](https://nodejs.org/api/buffer.html) | null\></code> —— <code>[Buffer](https://nodejs.org/api/buffer.html) | null</code>
* The binary image data of the screenshot, with the format specified in `options.format`. `null` is returned instead if `save` was passed into the `config` parameter.
##### Throws
* [`InvalidConfigurationError`](#invalidconfigurationerror)
##### Example
```ts
import { captureActiveWindow, captureActiveWindowSync } from 'windows-ss';
await captureActiveWindow();
captureActiveWindowSync();
```
### Interfaces
#### `Configuration`
Contains options that can be provided by the user when taking a screenshot.
##### Properties
* *(Optional)* <code>format: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code> — The format of the returned buffer & saved file.
* **Default** — `'png'`
* **Valid Values**
* `'png'`
* `'jpg' `
* `'jpeg'`
* `'bmp' `
* `'emf' `
* `'exif'`
* `'gif'`
* `'icon'`
* `'tiff'`
* `'wmf'`
* *(Optional)* <code>crop: [PlainRectangle](#plainrectangle)</code> — How much to carve off the edges.
* *(Optional)* <code>bounds: [PlainRectangle](#plainrectangle)</code> — The bounds where the screen will be captured.
* *(Optional)* <code>save: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code> — The path to where the screenshot will be saved to.
* > Note: If this property is not provided, the screenshot is simply returned as a [Buffer](https://nodejs.org/api/buffer.html).
#### `MonitorInfo`
Contains a description of a monitor.
##### Properties
* <code>monitor: [PlainRectangle](#plainrectangle)</code> — The resolution of the entire monitor.
* <code>workArea: [PlainRectangle](#plainrectangle)</code> — The resolution of the entire monitor excluding the taskbar.
* <code>deviceName: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code> — The device name of the monitor.
#### `PlainRectangle`
Contains properties to form a plain rectangle.
##### Properties
* <code>left: [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)</code> — The left edge of the rectangle.
* > **IMPORTANT**: This must be of `int` type, meaning no decimals. Else, it will fail applying configuration.
* <code>top: [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)</code> — The top edge of the rectangle.
* > **IMPORTANT**: This must be of `int` type, meaning no decimals. Else, it will fail applying configuration.
* <code>right: [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)</code> — The right edge of the rectangle.
* > **IMPORTANT**: This must be of `int` type, meaning no decimals. Else, it will fail applying configuration.
* <code>bottom: [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)</code> — The bottom edge of the rectangle.
* > **IMPORTANT**: This must be of `int` type, meaning no decimals. Else, it will fail applying configuration.
### Errors
#### `NoMatchError`
Thrown when no match can be found with the provided arguments.
##### Extends
* [`CSArgumentError`](#csargumenterror)
##### Properties
* *(Inherited)* <code>paramName: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>name: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>stack: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>raw: CSException</code>
#### `InvalidArgumentCountError`
Thrown when an invalid amount of arguments were provided.
##### Extends
* [`CSArgumentError`](#csargumenterror)
##### Properties
* *(Inherited)* <code>paramName: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>name: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>stack: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>raw: CSException</code>
#### `InvalidConfigurationError`
Thrown when an invalid [`Configuration`](#configuration) object was provided.
##### Extends
* [`CSArgumentError`](#csargumenterror)
##### Properties
* *(Inherited)* <code>paramName: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>name: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>stack: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>raw: CSException</code>
#### *(Internal)* `CSArgumentError`
Based on C#'s `ArgumentException`.
##### Extends
* [`CSError`](#cserror)
##### Properties
* <code>paramName: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>name: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>stack: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>raw: CSException</code>
#### *(Internal)* `CSError`
Based on C#'s `SystemException`.
##### Extends
* `ClientError`
* An internal wrapper for [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)
##### Properties
* <code>raw: CSException</code>
* The `InnerException` property of the raw [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) object thrown by `edge-js`
* *(Inherited)* <code>name: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
* *(Inherited)* <code>stack: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)</code>
## Contributing
All contributions are welcome. File an [issue](https://github.com/sxxov/windows-ss/issues) if you find something wrong, & a [pull request](https://github.com/sxxov/windows-ss/pulls) if you can fix it.
## License
[MIT](https://opensource.org/licenses/MIT).