{"id":25518680,"url":"https://github.com/sxxov/windows-ss","last_synced_at":"2025-04-11T00:05:34.701Z","repository":{"id":57397883,"uuid":"393083606","full_name":"sxxov/windows-ss","owner":"sxxov","description":"Screenshot quickly on NodeJS with native Windows API's.","archived":false,"fork":false,"pushed_at":"2021-08-12T20:18:12.000Z","size":10403,"stargazers_count":8,"open_issues_count":2,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T22:33:38.352Z","etag":null,"topics":["csharp","desktop-screenshot","dotnet","edge-js","javascript","library","native","nodejs","screen-capture","screenshot","screenshot-desktop","screenshot-utility","screenshots","speed","typescript","windows"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sxxov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-08-05T15:01:55.000Z","updated_at":"2023-09-13T23:53:11.000Z","dependencies_parsed_at":"2022-09-04T13:22:09.119Z","dependency_job_id":null,"html_url":"https://github.com/sxxov/windows-ss","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sxxov%2Fwindows-ss","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sxxov%2Fwindows-ss/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sxxov%2Fwindows-ss/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sxxov%2Fwindows-ss/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sxxov","download_url":"https://codeload.github.com/sxxov/windows-ss/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248068122,"owners_count":21042428,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","desktop-screenshot","dotnet","edge-js","javascript","library","native","nodejs","screen-capture","screenshot","screenshot-desktop","screenshot-utility","screenshots","speed","typescript","windows"],"created_at":"2025-02-19T16:54:12.366Z","updated_at":"2025-04-11T00:05:34.660Z","avatar_url":"https://github.com/sxxov.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# windows-ss\n\n[![npm version](https://badge.fury.io/js/windows-ss.svg)](https://badge.fury.io/js/windows-ss)\n\nTake screenshots quickly on Windows by communicating directly with native API's.\n\n\u003e Did I mention that it's DPI aware too?\n\n\n\n## Benchmark\n\nUsing [this repo](https://github.com/sxxov/windows-ss-benchmark). The numbers below were taken over 1000 runs, each at 2560x1440\u003csup\u003e\\*\u003c/sup\u003e, outputing `bmp`.\n\n| Library            | Save to buffer | Save to file |\n| ------------------ | -------------- | ------------ |\n| windows-ss         | **52ms**       | **51ms**     |\n| screenshot-desktop | 152ms          | 141ms        |\n| desktop-screenshot | n/a            | 63ms\u003csup\u003e\\*\\*\u003c/sup\u003e    |\n\n\u003csup\u003e\\*\u003c/sup\u003e  Except for `desktop-screenshot`, it ran at 1706x960 as it's DPI unaware.\n\n\u003csup\u003e\\*\\*\u003c/sup\u003e  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`\n\n\n\n## Installation\n\n```bash\nnpm i windows-ss\n```\n\n\u003e **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.\n\n\n\n## Usage\n\n```ts\nimport { capturePrimaryMonitor } from 'windows-ss';\n\nawait capturePrimaryMonitor({    \n    // The format of the returned Buffer \u0026 saved file.\n    format: 'png',\n    \n    // How much to carve off the edges. (Left, Top, Right, Bottom)\n    crop: {\n        left: 0,\n        top: 0,\n        right: 0,\n        bottom: 0,\n    },\n    \n    // The bounds where the screen will be captured. (Left, Top, Right, Bottom)\n    bounds: {\n        left: 0,\n        top: 0,\n        right: 0,\n        bottom: 0,\n    },\n    \n    // The file the screenshot will be saved to.\n    save: './ss.png', \n});\n```\n\n\n\n## API\n\n### Table of Contents\n\n* [Methods](#methods)\n  * \u003ccode\u003e[getMonitorInfos](#getMonitorInfos)\u003c/code\u003e\n  * \u003ccode\u003e[getMonitorInfosSync](#getMonitorInfosSync)\u003c/code\u003e\n  * \u003ccode\u003e[captureMonitorByIndex](#captureMonitorByIndex)\u003c/code\u003e\n  * \u003ccode\u003e[captureMonitorByIndexSync](#captureMonitorByIndexSync)\u003c/code\u003e\n  * \u003ccode\u003e[captureMonitorByName](#captureMonitorByName)\u003c/code\u003e\n  * \u003ccode\u003e[captureMonitorByNameSync](#captureMonitorByNameSync)\u003c/code\u003e\n  * \u003ccode\u003e[captureWindowByTitle](#captureWindowByTitle)\u003c/code\u003e\n  * \u003ccode\u003e[captureWindowByTitleSync](#captureWindowByTitleSync)\u003c/code\u003e\n  * \u003ccode\u003e[captureActiveWindow](#captureActiveWindow)\u003c/code\u003e\n  * \u003ccode\u003e[captureActiveWindowSync](#captureActiveWindowSync)\u003c/code\u003e\n* [Interfaces](#interfaces)\n  * [`Configuration`](#configuration)\n  * [`MonitorInfo`](#monitorinfo)\n  * [`PlainRectangle`](#plainrectangle)\n* [Errors](#errors)\n  * [`NoMatchError`](#NoMatchError)\n  * [`InvalidArgumentCountError`](#InvalidArgumentCountError)\n  * [`InvalidConfigurationError`](InvalidConfigurationError)\n\n\n\n### Methods\n\n#### `getMonitorInfos`\n\n#### `getMonitorInfosSync`\n\nReturns information about the the currently connected monitors.\n\n##### Parameters\n\n* n/a\n\n##### Returns\n\n* \u003ccode\u003ePromise\\\u003c[MonitorInfo](#monitorinfo)[]\\\u003e\u003c/code\u003e  —— \u003ccode\u003e[MonitorInfo](#monitorinfo)[]\u003c/code\u003e\n  * An array of [`MonitorInfo`](#monitorinfo)s gotten from the current system.\n\n##### Throws\n\n* n/a\n\n##### Example\n\n```ts\nimport { getMonitorInfos, getMonitorInfosSync } from 'windows-ss';\n\nawait getMonitorInfos();\ngetMonitorInfosSync();\n/*\n\t// Example output\n    [\n      {\n        monitor: { left: 0, top: 0, right: 2560, bottom: 1440 },\n        workArea: { left: 0, top: 0, right: 2560, bottom: 1380 },\n        deviceName: '\\\\\\\\.\\\\DISPLAY1'\n      },\n      {\n        monitor: { left: 304, top: -1080, right: 2224, bottom: 0 },\n        workArea: { left: 304, top: -1080, right: 2224, bottom: -40 },\n        deviceName: '\\\\\\\\.\\\\DISPLAY2'\n      }\n    ]\n*/\n```\n\n\n\n#### `captureMonitorByIndex`\n\n#### `captureMonitorByIndexSync`\n\nCaptures a screenshot of the monitor matching the device index.\n\n##### Parameters\n\n* \u003ccode\u003edeviceIndex: [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)\u003c/code\u003e \n  * Index of monitor according to Windows.\n* *(Optional)*  \u003ccode\u003econfig: [Configuration](#configuration)\u003c/code\u003e \n  * Additional options for capturing the screenshot.\n\n##### Returns\n\n* \u003ccode\u003ePromise\\\u003c[Buffer](https://nodejs.org/api/buffer.html) | null\\\u003e\u003c/code\u003e —— \u003ccode\u003e[Buffer](https://nodejs.org/api/buffer.html) | null\u003c/code\u003e\n  * 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.\n\n##### Throws\n\n* [`NoMatchError`](#nomatcherror)\n* [`InvalidArgumentCountError`](#invalidargumentcounterror)\n* [`InvalidConfigurationError`](#invalidconfigurationerror)\n\n##### Example\n\n```ts\nimport { captureMonitorByIndex, captureMonitorByIndexSync, getMonitorInfos } from 'windows-ss';\n\nconst monitorInfos = await getMonitorInfos();\n\nawait captureMonitorByIndex(monitorInfos.length - 1);\ncaptureMonitorByIndexSync(0);\n```\n\n\n\n#### `captureMonitorByName`\n\n#### `captureMonitorByNameSync`\n\nCaptures a screenshot of the monitor matching the device name.\n\n##### Parameters\n\n* \u003ccode\u003edeviceName: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e \n  * Name of monitor according to Windows.\n* *(Optional)*  \u003ccode\u003econfig: [Configuration](#configuration)\u003c/code\u003e \n  * Additional options for capturing the screenshot.\n\n##### Returns\n\n* \u003ccode\u003ePromise\\\u003c[Buffer](https://nodejs.org/api/buffer.html) | null\\\u003e\u003c/code\u003e —— \u003ccode\u003e[Buffer](https://nodejs.org/api/buffer.html) | null\u003c/code\u003e\n  * 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.\n\n##### Throws\n\n* [`NoMatchError`](#nomatcherror)\n* [`InvalidArgumentCountError`](#invalidargumentcounterror)\n* [`InvalidConfigurationError`](#invalidconfigurationerror)\n\n##### Example\n\n```ts\nimport { captureMonitorByName, captureMonitorByNameSync, getMonitorInfos } from 'windows-ss';\n\nconst monitorInfos = await getMonitorInfos();\n\nawait captureMonitorByName(monitorInfos[0].deviceName);\ncaptureMonitorByNameSync(String.raw`\\\\.\\DISPLAY1`);\n```\n\n\n\n#### `capturePrimaryMonitor`\n\n#### `capturePrimaryMonitorSync`\n\nCaptures a screenshot of the primary monitor.\n\n##### Parameters\n\n* *(Optional)*  \u003ccode\u003econfig: [Configuration](#configuration)\u003c/code\u003e \n  * Additional options for capturing the screenshot.\n\n##### Returns\n\n* \u003ccode\u003ePromise\\\u003c[Buffer](https://nodejs.org/api/buffer.html) | null\\\u003e\u003c/code\u003e —— \u003ccode\u003e[Buffer](https://nodejs.org/api/buffer.html) | null\u003c/code\u003e\n  * 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.\n\n##### Throws\n\n* [`InvalidConfigurationError`](#invalidconfigurationerror)\n\n##### Example\n\n```ts\nimport { capturePrimaryMonitor, capturePrimaryMonitorSync } from 'windows-ss';\n\nawait capturePrimaryMonitor();\ncapturePrimaryMonitorSync();\n```\n\n\n\n#### `captureWindowByTitle`\n\n#### `captureWindowByTitleSync`\n\nCaptures a screenshot of the window matching the title.\n\n##### Parameters\n\n* \u003ccode\u003etitle: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e \n  * Title of window.\n* *(Optional)*  \u003ccode\u003econfig: [Configuration](#configuration)\u003c/code\u003e \n  * Additional options for capturing the screenshot.\n\n##### Returns\n\n* \u003ccode\u003ePromise\\\u003c[Buffer](https://nodejs.org/api/buffer.html) | null\\\u003e\u003c/code\u003e —— \u003ccode\u003e[Buffer](https://nodejs.org/api/buffer.html) | null\u003c/code\u003e\n  * 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.\n\n##### Throws\n\n* [`NoMatchError`](#nomatcherror)\n* [`InvalidArgumentCountError`](#invalidargumentcounterror)\n* [`InvalidConfigurationError`](#invalidconfigurationerror)\n\n##### Example\n\n```ts\nimport { captureWindowByTitle, captureWindowByTitleSync } from 'windows-ss';\n\nawait captureWindowByTitle('Task Manager');\ncaptureWindowByTitleSync('Notepad');\n```\n\n\n\n#### `captureActiveWindow`\n\n#### `captureActiveWindowSync`\n\nCaptures a screenshot of the currently active/focused window.\n\n##### Parameters\n\n* *(Optional)*  \u003ccode\u003econfig: [Configuration](#configuration)\u003c/code\u003e \n  * Additional options for capturing the screenshot.\n\n##### Returns\n\n* \u003ccode\u003ePromise\\\u003c[Buffer](https://nodejs.org/api/buffer.html) | null\\\u003e\u003c/code\u003e —— \u003ccode\u003e[Buffer](https://nodejs.org/api/buffer.html) | null\u003c/code\u003e\n  * 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.\n\n##### Throws\n\n* [`InvalidConfigurationError`](#invalidconfigurationerror)\n\n##### Example\n\n```ts\nimport { captureActiveWindow, captureActiveWindowSync } from 'windows-ss';\n\nawait captureActiveWindow();\ncaptureActiveWindowSync();\n```\n\n\n\n### Interfaces\n\n#### `Configuration`\n\nContains options that can be provided by the user when taking a screenshot.\n\n##### Properties\n\n*  *(Optional)*  \u003ccode\u003eformat: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e — The format of the returned buffer \u0026 saved file.\n   \n   *  **Default** — `'png'`\n   *  **Valid Values**\n      *  `'png'`\n      *  `'jpg' `\n      *  `'jpeg'`\n      *  `'bmp' `\n      *  `'emf' `\n      *  `'exif'`\n      *  `'gif'`\n      *  `'icon'`\n      *  `'tiff'`\n      *  `'wmf'`\n   \n* *(Optional)*  \u003ccode\u003ecrop: [PlainRectangle](#plainrectangle)\u003c/code\u003e — How much to carve off the edges.\n\n* *(Optional)*  \u003ccode\u003ebounds: [PlainRectangle](#plainrectangle)\u003c/code\u003e — The bounds where the screen will be captured.\n\n* *(Optional)* \u003ccode\u003esave: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e — The path to where the screenshot will be saved to.\n\n  * \u003e Note: If this property is not provided, the screenshot is simply returned as a [Buffer](https://nodejs.org/api/buffer.html).\n\n\n\n#### `MonitorInfo`\n\nContains a description of a monitor.\n\n##### Properties\n\n* \u003ccode\u003emonitor: [PlainRectangle](#plainrectangle)\u003c/code\u003e — The resolution of the entire monitor.\n* \u003ccode\u003eworkArea: [PlainRectangle](#plainrectangle)\u003c/code\u003e — The resolution of the entire monitor excluding the taskbar.\n* \u003ccode\u003edeviceName: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e — The device name of the monitor.\n\n\n\n#### `PlainRectangle`\n\nContains properties to form a plain rectangle.\n\n##### Properties\n\n* \u003ccode\u003eleft: [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)\u003c/code\u003e — The left edge of the rectangle.\n\n  * \u003e **IMPORTANT**: This must be of `int` type, meaning no decimals. Else, it will fail applying configuration.\n\n* \u003ccode\u003etop: [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)\u003c/code\u003e — The top edge of the rectangle.\n\n  * \u003e **IMPORTANT**: This must be of `int` type, meaning no decimals. Else, it will fail applying configuration.\n\n* \u003ccode\u003eright: [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)\u003c/code\u003e — The right edge of the rectangle.\n\n  * \u003e **IMPORTANT**: This must be of `int` type, meaning no decimals. Else, it will fail applying configuration.\n\n* \u003ccode\u003ebottom: [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)\u003c/code\u003e — The bottom edge of the rectangle.\n\n  * \u003e **IMPORTANT**: This must be of `int` type, meaning no decimals. Else, it will fail applying configuration.\n\n\n\n### Errors\n\n#### `NoMatchError`\n\nThrown when no match can be found with the provided arguments.\n\n##### Extends\n\n* [`CSArgumentError`](#csargumenterror)\n\n##### Properties\n\n* *(Inherited)* \u003ccode\u003eparamName: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003ename: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003estack: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003eraw: CSException\u003c/code\u003e\n\n\n\n#### `InvalidArgumentCountError`\n\nThrown when an invalid amount of arguments were provided.\n\n##### Extends\n\n* [`CSArgumentError`](#csargumenterror)\n\n##### Properties\n\n* *(Inherited)* \u003ccode\u003eparamName: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003ename: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003estack: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003eraw: CSException\u003c/code\u003e\n\n\n\n#### `InvalidConfigurationError`\n\nThrown when an invalid [`Configuration`](#configuration) object was provided.\n\n##### Extends\n\n* [`CSArgumentError`](#csargumenterror)\n\n##### Properties\n\n* *(Inherited)* \u003ccode\u003eparamName: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003ename: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003estack: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003eraw: CSException\u003c/code\u003e\n\n\n\n#### *(Internal)* `CSArgumentError`\n\nBased on C#'s `ArgumentException`.\n\n##### Extends\n\n* [`CSError`](#cserror)\n\n##### Properties\n\n* \u003ccode\u003eparamName: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003ename: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003estack: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003eraw: CSException\u003c/code\u003e\n\n\n\n#### *(Internal)* `CSError`\n\nBased on C#'s `SystemException`.\n\n##### Extends\n\n* `ClientError`\n  * An internal wrapper for [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)\n\n##### Properties\n\n* \u003ccode\u003eraw: CSException\u003c/code\u003e\n  * 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`\n* *(Inherited)* \u003ccode\u003ename: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n* *(Inherited)* \u003ccode\u003estack: [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)\u003c/code\u003e\n\n\n\n## Contributing\n\nAll contributions are welcome. File an [issue](https://github.com/sxxov/windows-ss/issues) if you find something wrong, \u0026 a [pull request](https://github.com/sxxov/windows-ss/pulls) if you can fix it.\n\n\n\n## License\n\n[MIT](https://opensource.org/licenses/MIT).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsxxov%2Fwindows-ss","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsxxov%2Fwindows-ss","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsxxov%2Fwindows-ss/lists"}