{"id":15687585,"url":"https://github.com/discretetom/rusty-duplication","last_synced_at":"2025-05-07T17:20:39.303Z","repository":{"id":164701076,"uuid":"639544288","full_name":"DiscreteTom/rusty-duplication","owner":"DiscreteTom","description":"Capture the screen on Windows using the Desktop Duplication API in Rust, with shared memory support.","archived":false,"fork":false,"pushed_at":"2025-02-23T11:22:44.000Z","size":199,"stargazers_count":11,"open_issues_count":6,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-20T00:38:17.581Z","etag":null,"topics":["desktop-duplication-api","rust","shared-memory","windows"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DiscreteTom.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-05-11T17:15:50.000Z","updated_at":"2025-04-10T11:47:30.000Z","dependencies_parsed_at":null,"dependency_job_id":"4ba6310c-57ac-41cd-bfc7-816f3ea5c361","html_url":"https://github.com/DiscreteTom/rusty-duplication","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiscreteTom%2Frusty-duplication","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiscreteTom%2Frusty-duplication/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiscreteTom%2Frusty-duplication/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiscreteTom%2Frusty-duplication/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DiscreteTom","download_url":"https://codeload.github.com/DiscreteTom/rusty-duplication/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252922308,"owners_count":21825641,"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":["desktop-duplication-api","rust","shared-memory","windows"],"created_at":"2024-10-03T17:50:14.290Z","updated_at":"2025-05-07T17:20:39.261Z","avatar_url":"https://github.com/DiscreteTom.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rusty-duplication\n\n[![license](https://img.shields.io/crates/l/rusty-duplication?style=flat-square)](https://crates.io/crates/rusty-duplication)\n[![version](https://img.shields.io/crates/v/rusty-duplication?style=flat-square)](https://crates.io/crates/rusty-duplication)\n[![docs.rs](https://img.shields.io/docsrs/rusty-duplication?style=flat-square)](https://docs.rs/rusty-duplication/latest)\n\nCapture the screen on Windows using the Desktop Duplication API in Rust, with shared memory support.\n\n## Installation\n\n```sh\ncargo add rusty-duplication\n```\n\n## Usage\n\n### Basic Usage\n\n```rust\nuse rusty_duplication::{FrameInfoExt, Scanner, VecCapturer};\nuse std::{fs::File, io::Write, thread, time::Duration};\n\n// create a scanner to scan for monitors\nlet mut scanner = Scanner::new().unwrap();\n\n// scanner implements Iterator, you can use it to iterate through monitors\nlet monitor = scanner.next().unwrap();\n\n// get monitor info\nmonitor.dxgi_output_desc().unwrap();\nmonitor.dxgi_outdupl_desc();\n\n// create a vec capturer for a monitor\n// this will allocate memory buffer to store pixel data\nlet mut capturer: VecCapturer = monitor.try_into().unwrap();\n\n// you can also get monitor info from a capturer\nlet dxgi_outdupl_desc = capturer.monitor().dxgi_outdupl_desc();\nlet dxgi_output_desc = capturer.monitor().dxgi_output_desc().unwrap();\n// get resolution width/height\nprintln!(\n  \"size: {}x{}\",\n  dxgi_outdupl_desc.ModeDesc.Width, dxgi_outdupl_desc.ModeDesc.Height\n);\n// get position\nprintln!(\n  \"left: {}, top: {}, right: {}, bottom: {}\",\n  dxgi_output_desc.DesktopCoordinates.left,\n  dxgi_output_desc.DesktopCoordinates.top,\n  dxgi_output_desc.DesktopCoordinates.right,\n  dxgi_output_desc.DesktopCoordinates.bottom\n);\n\n// sleep for a while before capture to wait system to update the screen\nthread::sleep(Duration::from_millis(100));\n\n// capture desktop image and get the frame info\nlet info = capturer.capture().unwrap();\n\n// we have some extension methods for the frame info\nif info.desktop_updated() {\n  println!(\"captured!\");\n}\nif info.mouse_updated() {\n  println!(\"mouse updated!\");\n}\nif info.pointer_shape_updated() {\n  println!(\"pointer shape updated!\");\n}\n\n// write to a file\nlet mut file = File::create(\"capture.bin\").unwrap();\n// the buffer is in BGRA32 format\nfile.write_all(\u0026capturer.buffer).unwrap();\n```\n\n### Shared Memory\n\nYou can use shared memory to share the frame buffer between processes.\n\n```rust\nuse rusty_duplication::{CapturerBuffer, FrameInfoExt, Scanner, SharedMemoryCapturer};\nuse std::{fs::File, io::Write, thread, time::Duration};\n\nlet monitor = Scanner::new().unwrap().next().unwrap();\n\n// create a shared memory capturer by creating a shared memory with the provided name\nlet mut capturer = SharedMemoryCapturer::create(monitor, \"SharedMemoryName\").unwrap();\n// you can also use `SharedMemoryCapturer::open` to open an existing shared memory\n\n// sleep for a while before capture to wait system to update the screen\nthread::sleep(Duration::from_millis(50));\n\nlet info = capturer.capture().unwrap();\nassert!(info.desktop_updated());\n\n// write to a file\nlet mut file = File::create(\"capture.bin\").unwrap();\n// the buffer is in BGRA32 format\nfile.write_all(capturer.buffer.as_bytes()).unwrap();\n```\n\n\u003e [!NOTE]\n\u003e If your shared memory name starts with `Global\\`, you may need to run your app in administrator mode. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga.\n\n### Customized Capturer\n\nYou can implement `CapturerBuffer` for your own type to create a customized capturer. You can refer to [`VecCapturer`](./src/capturer/vec.rs)'s implementation.\n\n## [Examples](./examples/)\n\n## [Documentation](https://docs.rs/rusty-duplication/)\n\n## Credit\n\nThis project is based on the following projects:\n\n- https://github.com/bryal/dxgcap-rs\n- https://github.com/microsoft/windows-rs\n- https://github.com/hecomi/uDesktopDuplication\n\n## [CHANGELOG](./CHANGELOG.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiscretetom%2Frusty-duplication","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdiscretetom%2Frusty-duplication","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiscretetom%2Frusty-duplication/lists"}