A screen capture and stitching tool for KDE Plasma Wayland on Linux. Records your screen as you scroll and stitches all frames into a single tall image and PDF.
Some websites (university portals, paid course platforms) block PDF downloads or use scroll-locked viewers. Snapsure records the content as you scroll and stitches everything into one clean document.
- Click the tray icon → drag to select a region
- Recording starts immediately via GPU Screen Recorder (PipeWire, 30fps CPU-encoded H264)
- Scroll through the content at any pace
- Click the tray icon again to stop
- Frames are extracted, deduplicated, and stitched using template matching
- Output PNG + PDF saved to
captures/
- System tray — green "S" idle, red "S" recording
- Region selection — drag overlay to select capture area
- GPU Screen Recorder — PipeWire/XDG portal capture with CPU H264 encoding for AMD/NVIDIA compatibility
- Smart deduplication — drops near-identical frames (paused scrolling)
- Template matching stitcher — bottom-40% strip template at 1/8 resolution for coarse match, pixel MSE refinement for exact alignment
- Hard-cut seams — no alpha blending (blending creates colour banding on H264-encoded text)
- Saves to
captures/— timestamped PNG + PDF, Desktop stays clean - Notification buttons — "View Image" opens viewer, "Show in Folder" opens Dolphin with file selected
- KDE Plasma 6 (Wayland)
- Python 3.10+
- GPU Screen Recorder (
gpu-screen-recorderin PATH) notify-sendwith action support (libnotify ≥ 0.7.9)dolphin
On Arch / CachyOS:
yay -S gpu-screen-recorderOn first launch, KDE will show a screen share dialog — pick your screen. Subsequent runs skip the dialog automatically (portal session is cached).
Snapsure defaults to CPU H264 encoding through GPU Screen Recorder. That avoids vendor-specific encoder issues and keeps capture behavior consistent across AMD and NVIDIA systems.
git clone https://github.com/noonr48/snapsure.git
cd snapsure
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtsource .venv/bin/activate
python main.py- A green S icon appears in the system tray
- Click the tray icon — screen dims, drag to select the region to capture
- Recording starts immediately — icon turns red
- Scroll through your content at any pace (30fps CPU capture catches everything)
- Click the tray icon again to stop
- Stitching runs automatically — a notification appears when done
- Find your output in
captures/scroll_capture_YYYYMMDD_HHMMSS.{png,pdf}
If the tray icon stops responding, use the signal file to stop:
bash trigger.sh stop
# or directly:
echo stop > /tmp/wayyasnitch_signalsnapsure/
├── main.py # App entry, tray icon, state machine, signal file watcher
├── captures/ # Output directory (gitignored)
├── capture/
│ ├── qt_capture.py # VideoCapture: wraps gpu-screen-recorder, extracts frames
│ └── selection.py # Region selection overlay (Qt)
├── stitch/
│ └── matcher.py # find_overlap, deduplicate_frames, stitch_frames
├── output/
│ └── pdf_generator.py # save_as_image, save_as_pdf → captures/
├── utils/
│ └── notifications.py # notify_with_file_open (notify-send --wait + actions)
└── config/
└── settings.py # Constants
gpu-screen-recorder records via the PipeWire XDG desktop portal at 30fps using CPU-encoded H264 with no cursor. CPU encoding is the default for cross-vendor compatibility on Wayland, avoiding NVIDIA/AMD-specific encoder differences. On stop, SIGINT is sent for clean MP4 finalization. Frames are extracted at ~5fps using OpenCV (every 6th frame from 30fps video) and cropped to the selected region.
For each consecutive frame pair:
- Coarse — use bottom 40% of previous frame as template; search in current frame at 1/8 resolution via
cv2.matchTemplate(TM_CCOEFF_NORMED). Overlap =match_y + template_height. - Refine — pixel MSE scan at full resolution in ±32px window around coarse estimate. Picks the exact pixel offset with minimum squared error.
- Cut — hard vstack at the refined overlap. No blending: alpha-blending H264 frames creates visible horizontal colour bands on text content.
Deduplication uses downsampled MSE with threshold 0.998 — aggressive enough to drop stationary frames, lenient enough to keep slow scrolls.
All require wlroots. KDE uses kwin — incompatible. GPU Screen Recorder uses the XDG desktop portal (PipeWire) which works on any compositor.
PyQt5>=5.15
opencv-python>=4.5
numpy>=1.20
Pillow>=8.0
img2pdf>=0.4
MIT