miniscreenshot
A pluggable, multi-crate Rust workspace for taking screenshots of windowed applications or the entire desktop.
Crate overview
| Crate | Description |
|---|---|
miniscreenshot |
Core — Screenshot type, PNG / PPM / PGM encoding, ScreenshotProvider / AsyncScreenshotProvider traits |
miniscreenshot-softbuffer |
softbuffer integration + re-export. Enable the winit feature to re-export winit alongside softbuffer. |
miniscreenshot-wgpu |
wgpu texture readback + re-export |
miniscreenshot-wayland |
Wayland wlr-screencopy-v1 system capture + re-exports |
miniscreenshot-x11 |
X11 (XGetImage / MIT-SHM) system capture + re-exports |
miniscreenshot-portal |
XDG Desktop Portal (ashpd) system capture; works on GNOME, KDE, wlroots, and inside Flatpak/Snap |
miniscreenshot-skia |
skia-safe re-export + surface screenshot helper |
miniscreenshot-vello |
vello re-export + pixel readback support |
Design goals
- Pluggable — each rendering backend is a separate crate. Applications depend only on what they use.
- No version conflicts — every driver crate re-exports its underlying
library (e.g.,
miniscreenshot_wgpu::wgpu). Depending on a driver crate is sufficient; no separatewgpu/winit/… dependency required. - Low-friction output formats — PNG (default), PPM and PGM are supported out of the box. Format is inferred from the file extension.
- System screenshots — Linux Wayland via
zwlr_screencopy_manager_v1(wlroots-based compositors: Sway, Hyprland, …), X11 viaXGetImagewith an MIT-SHM fast path, and XDG Desktop Portal viaashpd(GNOME, KDE, Flatpak, Snap).
Quick start
Core crate
[]
= "0.1"
use Screenshot;
// Build from raw RGBA8 pixel data
let data = vec!; // 1×1 red pixel
let shot = from_rgba;
// Save — format inferred from extension (.png / .ppm / .pgm)
shot.save.unwrap;
// Or encode to bytes explicitly
let png_bytes: = shot.encode_png.unwrap;
let ppm_bytes: = shot.encode_ppm; // lossless, trivial format
let pgm_bytes: = shot.encode_pgm; // grayscale
softbuffer backend
[]
= "0.1"
use ;
// softbuffer stores pixels as u32 XRGB8888 values
let pixels: & = /* buffer.deref() from softbuffer */ &;
let shot = screenshot_from_xrgb;
shot.save.unwrap;
softbuffer + winit pairing
When you want to create a softbuffer::Surface from a winit::Window, enable
the winit feature. This re-exports winit alongside softbuffer at the same
version, avoiding dependency conflicts.
[]
= { = "0.1", = ["winit"] }
use Window;
use softbuffer;
use Rc;
// Rc<Window> implements the raw-handle traits softbuffer needs.
let window: = /* create window */;
let ctx = new.unwrap;
let surface = new.unwrap;
See the softbuffer_winit_scene_screenshot example for a complete demo.
wgpu backend
[]
= "0.1"
use ;
// `texture` must have been created with TextureUsages::COPY_SRC
let shot = capture_texture.unwrap;
shot.save.unwrap;
Wayland system screenshot
[]
= "0.1"
use WaylandCapture;
let mut cap = connect.expect;
println!;
// Capture first monitor
let shot = cap.capture_output.expect;
shot.save.unwrap;
// Or capture all monitors at once
let shots = cap.capture_all.expect;
Compositor requirements: Requires a Wayland compositor that implements
zwlr_screencopy_manager_v1(wlroots-based — Sway, Hyprland, weston, cage, labwc, …). GNOME-on-Wayland and KWin do not implement this protocol and will returnWaylandCaptureError::NoScreencopyManager. Useminiscreenshot-portalinstead on these compositors.
X11 system screenshot
[]
= "0.1"
use X11Capture;
let mut cap = connect.expect;
println!;
// Capture first screen
let shot = cap.capture_screen.expect;
shot.save.unwrap;
// Or capture all screens at once
let shots = cap.capture_all.expect;
Server requirements: Requires a reachable X11 server (
$DISPLAYset). Uses MIT-SHM when available for a fast-path capture; otherwise falls back to a plainXGetImagetransfer over the wire.
Screenshot portal (GNOME / KDE / Flatpak)
[]
= "0.1"
Blocking usage (default):
use PortalCapture;
let mut cap = connect.expect;
let shot = cap.capture_interactive.expect;
shot.save.unwrap;
Async usage:
[]
= { = "0.1", = false, = ["tokio"] }
use PortalCapture;
async
Portal requirements: Requires a running desktop session with
$XDG_RUNTIME_DIRand a portal implementation (xdg-desktop-portal+ a backend such asxdg-desktop-portal-gnome,-kde,-wlr, or-gtk). GNOME always shows a confirmation dialog; KDE and wlroots may or may not depending on backend policy. Works inside Flatpak and Snap sandboxes. Use this crate on GNOME or KWin instead ofminiscreenshot-wayland.
ScreenshotProvider trait
All driver crates implement (or wrap types that implement) the core
ScreenshotProvider trait, making backends interchangeable:
use ScreenshotProvider;
Optional features
# Winit (for softbuffer + winit integration)
= { = "0.1", = ["winit"] }
Async traits
The core miniscreenshot crate exposes the AsyncScreenshotProvider trait
with zero additional dependencies (the trait uses return-position
impl Trait). It is always available — no feature flag required:
= "0.1"
Portal features
miniscreenshot-portal exposes runtime and API-surface features. Enabling
a runtime (tokio or async-std) automatically enables the async API surface.
# Default: tokio runtime + blocking API + async API
= "0.1"
# Async-only with tokio (no blocking convenience methods)
= { = "0.1", = false, = ["tokio"] }
# Async-only with async-std
= { = "0.1", = false, = ["async-std"] }
The tokio and async-std runtime features are mutually exclusive. The
blocking API-surface feature is independent. The async API surface is
implied by whichever runtime you select, but can also be enabled standalone
if you want to provide your own executor.
Output formats
| Format | Method | Notes |
|---|---|---|
| PNG | encode_png() / save("file.png") |
Lossless, widely supported |
| PPM | encode_ppm() / save("file.ppm") |
Binary P6, trivial to parse |
| PGM | encode_pgm() / save("file.pgm") |
Binary P5 grayscale (BT.601 luma) |
Examples
Each crate ships with a self-contained examples/<crate_short>_scene_screenshot.rs that
renders a scene (or synthesises a buffer) and saves a PNG.
| Crate | Command | Headless? |
|---|---|---|
miniscreenshot (core) |
cargo run -p miniscreenshot --example core_scene_screenshot |
Yes |
miniscreenshot-softbuffer |
cargo run -p miniscreenshot-softbuffer --example softbuffer_scene_screenshot |
Yes |
miniscreenshot-softbuffer (winit) |
cargo run -p miniscreenshot-softbuffer --example softbuffer_winit_scene_screenshot --features winit |
No (needs a display) |
miniscreenshot-wgpu |
cargo run -p miniscreenshot-wgpu --example wgpu_scene_screenshot |
Yes |
miniscreenshot-wayland |
cargo run -p miniscreenshot-wayland --example wayland_scene_screenshot |
No (needs wlroots-based Wayland compositor) |
miniscreenshot-x11 |
cargo run -p miniscreenshot-x11 --example x11_scene_screenshot |
No (needs $DISPLAY / X11 server) |
miniscreenshot-portal |
cargo run -p miniscreenshot-portal --example portal_scene_screenshot |
No (needs desktop session with portal) |
miniscreenshot-portal (async) |
cargo run -p miniscreenshot-portal --example portal_async_scene_screenshot --features async |
No (needs desktop session with portal) |
miniscreenshot-skia |
cargo run -p miniscreenshot-skia --example skia_scene_screenshot |
Yes |
miniscreenshot-vello |
cargo run -p miniscreenshot-vello --example vello_scene_screenshot |
Yes |
Build all examples at once:
Build and run all headless examples:
License
Licensed under either of Apache License 2.0 or MIT License at your option.