{"id":49028423,"url":"https://github.com/dimitar-radenkov/pointframe","last_synced_at":"2026-05-10T20:31:01.789Z","repository":{"id":342094593,"uuid":"1170499336","full_name":"dimitar-radenkov/Pointframe","owner":"dimitar-radenkov","description":"Lightweight WPF screen capture, annotation, OCR and screen recorder for Windows. Free alternative to Snagit/Greenshot.","archived":false,"fork":false,"pushed_at":"2026-04-28T05:39:27.000Z","size":843,"stargazers_count":5,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-04-28T07:06:39.274Z","etag":null,"topics":["annotation","dotnet","ocr","screen-capture","screen-recorder","screenshot","snipping-tool","windows","wpf"],"latest_commit_sha":null,"homepage":"https://dimitar-radenkov.github.io/Pointframe/","language":"C#","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/dimitar-radenkov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-02T07:31:36.000Z","updated_at":"2026-04-28T05:32:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dimitar-radenkov/Pointframe","commit_stats":null,"previous_names":["dimitar-radenkov/snippingtool","dimitar-radenkov/pointframe"],"tags_count":103,"template":false,"template_full_name":null,"purl":"pkg:github/dimitar-radenkov/Pointframe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimitar-radenkov%2FPointframe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimitar-radenkov%2FPointframe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimitar-radenkov%2FPointframe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimitar-radenkov%2FPointframe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dimitar-radenkov","download_url":"https://codeload.github.com/dimitar-radenkov/Pointframe/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dimitar-radenkov%2FPointframe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32559760,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T03:21:47.309Z","status":"ssl_error","status_checked_at":"2026-05-03T03:21:43.884Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["annotation","dotnet","ocr","screen-capture","screen-recorder","screenshot","snipping-tool","windows","wpf"],"created_at":"2026-04-19T08:04:10.555Z","updated_at":"2026-05-10T20:31:01.770Z","avatar_url":"https://github.com/dimitar-radenkov.png","language":"C#","funding_links":["https://paypal.me/DimitarRadenkov"],"categories":[],"sub_categories":[],"readme":"# Pointframe\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://dimitar-radenkov.github.io/Pointframe/\"\u003e\n    \u003cimg src=\"website/app-icon.png\" alt=\"Pointframe icon\" width=\"48\" height=\"48\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003ePointframe\u003c/h1\u003e\n\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003ePointframe is a screen capture and recording tool for Windows, built for bug reports, tutorials, and fast feedback.\u003c/b\u003e\u003cbr\u003e\n  Capture, annotate, blur, record, and share what matters without breaking your flow.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003e🌐 \u003ca href=\"https://dimitar-radenkov.github.io/Pointframe/\"\u003eVisit the Official Website\u003c/a\u003e\u003c/b\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/dimitar-radenkov/Pointframe/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/dimitar-radenkov/Pointframe/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/dimitar-radenkov/Pointframe\"\u003e\u003cimg src=\"https://codecov.io/gh/dimitar-radenkov/Pointframe/branch/master/graph/badge.svg\" alt=\"codecov\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/dimitar-radenkov/Pointframe/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/dimitar-radenkov/Pointframe?color=success\" alt=\"Latest release\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/microsoft/winget-pkgs/tree/master/manifests/d/DimitarRadenkov/Pointframe\"\u003e\u003cimg src=\"https://img.shields.io/winget/v/DimitarRadenkov.Pointframe?label=winget\u0026color=blue\" alt=\"winget\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/dimitar-radenkov/Pointframe/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/downloads/dimitar-radenkov/Pointframe/total?label=downloads\u0026color=purple\" alt=\"Downloads\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cvideo src=\"https://github.com/user-attachments/assets/d4e0c937-a845-4266-9454-2b816934f949\" width=\"100%\" controls autoplay loop muted\u003e\u003c/video\u003e\n\u003c/p\u003e\n\n## 🚀 Quick Start\n\nGet up and running in seconds using the Windows Package Manager (winget):\n\nStarting with the `5.0` release line, the winget package ID is `DimitarRadenkov.Pointframe`.\n\n```powershell\nwinget install DimitarRadenkov.Pointframe\n```\n\n*Prefer a manual install? Download the latest installer from the [Releases](https://github.com/dimitar-radenkov/Pointframe/releases) page.*\n\n1. Install Pointframe with `winget install DimitarRadenkov.Pointframe` or download the latest installer from [Releases](https://github.com/dimitar-radenkov/Pointframe/releases).\n2. Press `Print Screen` to open the capture overlay and select the region you want.\n3. Annotate, copy, save, pin, or record the region from the overlay and recording HUD.\n\nIf you find Pointframe useful, a ⭐ on GitHub helps others discover it — thank you!\n\n## ✨ Key highlights\n\n- **Live Video Annotations:** Draw, highlight, and redact *while* recording. No need for post-production video editing.\n- **Privacy First (Live Blur):** Drag over sensitive content (passwords, emails, API keys) to apply a live Gaussian blur that stays hidden in the final export.\n- **Built-in OCR:** Lasso any text on your screen (even in images or videos) to instantly copy it to your clipboard.\n- **Pin to Screen:** Pin captured screenshots as floating, always-on-top windows for quick reference while coding or writing.\n\n## Latest features\n\n- **Show your point while recording** — Draw on the captured region as you record, then switch between interactive and drawing modes from the HUD.\n- **Stay in control without breaking flow** — Pause, resume, stop, switch tools, clear annotations, and open the output folder from one floating HUD.\n- **Redact sensitive content live** — Blur annotations now sample from the live recording region, so private details stay hidden in the final video.\n\n## Why people use it\n\n- **Show the problem, not just describe it** — Bugs and UI issues are easier to understand when the screenshot or recording already contains the important highlights.\n- **Make tutorials easier to follow** — Arrows, text, and numbered steps keep people focused on what matters.\n- **Hide private details before sharing** — Blur emails, passwords, tokens, and anything else you do not want on screen.\n- **Work from one place** — Capture, annotate, copy, save, pin, and record without bouncing between tools.\n\n## Features\n\n- **Region capture** — Press the configured hotkey (default: `Print Screen`) to draw a selection on screen\n- **Whole-screen snip** — Instantly capture the entire screen from the tray icon or a dedicated hotkey\n- **Frozen screen snapshot** — The screen is captured instantly when the hotkey is pressed, freezing menus, tooltips, and popups exactly as they appear\n- **Selection magnifier** — A zoomed loupe follows your cursor while drawing the capture region for pixel-accurate selection\n- **Configurable capture hotkeys** — Change the region-capture hotkey and the whole-screen record hotkey independently from Settings\n- **Annotation tools** — Arrow, line, rectangle, circle, pen, highlighter, text, numbered labels, blur/pixelate, callout (speech bubble), color picker, pixel ruler\n- **Style presets** — Up to 5 named color-and-thickness shortcuts shown as quick-access dots in the annotation toolbar; fully configurable in Settings\n- **Color picker tool** — Sample any pixel color from the frozen screenshot; the loupe zooms in with a hex preview and sets the active annotation color\n- **Pixel ruler tool** — Draw a ruler across the screenshot to measure distances in pixels\n- **Blur tool** — Drag over sensitive content (faces, emails, passwords) to apply a Gaussian blur before sharing\n- **OCR — Copy Text** — Draw a lasso around text in the screenshot to extract it via OCR and copy to clipboard (uses Windows.Media.Ocr, no external dependencies)\n- **Open existing image** — Load a PNG, JPG/JPEG, or BMP from the tray menu and annotate it without taking a new screenshot\n- **Pin screenshot** — Pin the captured screenshot as a floating, always-on-top, resizable window for quick reference while you work\n- **Undo / redo** — Full undo/redo stack during annotation\n- **Copy \u0026 auto-save** — Copy to clipboard; optional auto-save to a configurable folder\n- **Screen recording** — Record a selected region to MP4 (H.264 via ffmpeg) or start a whole-screen recording instantly with `Ctrl+Shift+R` (default); optional microphone audio from a selected Windows input device\n- **Recording-time annotations** — Add shapes and text directly on top of a recording while it is in progress; switch between draw mode and interact mode from the floating HUD\n- **Cursor highlight** — Configurable glowing ring around the cursor during recording so viewers never lose track of your pointer\n- **Click ripple** — Visual ripple effect on mouse clicks during recording to make interactions obvious\n- **GIF export** — Export any recent recording to GIF directly from the tray's Recent recordings menu (requires ffmpeg)\n- **Capture delay** — Configurable countdown (0 / 3 / 5 / 10 s) before the selection overlay appears, useful for capturing menus and hover states\n- **Auto-updates** — A background service checks GitHub Releases on every launch and on a configurable schedule (every day / 2 days / 3 days). When a new version is found a tray balloon appears; click it to confirm, watch the progress bar, and the installer runs automatically — no browser, no manual downloads\n- **System tray** — Runs silently in the background; all actions accessible from the tray icon\n- **Theme support** — Choose Light, Dark, or follow the system theme from Settings\n\n## Use cases\n\n- **Bug reports** — Capture a precise region, annotate it, and copy or save the result for issue tracking and support requests\n- **Documentation** — Create quick step-by-step screenshots with arrows, numbered steps, and text callouts for guides and tutorials\n- **Live workflow capture** — Record a selected region while drawing annotations on top of the recording as you work\n- **Sensitive content redaction** — Blur passwords, emails, and other private details before sharing screenshots or recordings\n- **Text extraction** — Select text in a screenshot with OCR and copy it directly to the clipboard\n\n## System tray menu\n\nRight-click the tray icon to access all actions:\n\n| Item | Description |\n|---|---|\n| New Snip | Open the region-capture overlay (same as the capture hotkey) |\n| Whole screen snip | Instantly capture the entire screen |\n| Open image… | Load a PNG / JPG / BMP file and open it in the annotation overlay |\n| Recent captures | Submenu listing the last 5 saved screenshots; each has **Open** and **Open folder** actions |\n| Recent recordings | Submenu listing the last 5 recordings; each has **Open**, **Open folder**, and **Export to GIF** actions |\n| Settings | Open the Settings window |\n| Check for Updates | Manually trigger an update check against GitHub Releases |\n| About | Show version information |\n| Exit | Quit the application |\n\nLeft-clicking the tray icon triggers **New Snip** directly.\n\n## Settings\n\nOpen **Settings** from the tray icon to configure:\n\n### Capture\n\n| Setting | Description |\n|---|---|\n| Screenshot save folder | Where auto-saved screenshots are written |\n| Auto-save on copy | Automatically save every screenshot when copied |\n| Capture delay | Countdown (sec) before the selection overlay opens: 0 / 3 / 5 / 10 |\n| Capture hotkey | The key that triggers the region-capture overlay (default: `Print Screen`); supports modifier keys (Ctrl, Shift, Alt) |\n\n### Recording\n\n| Setting | Description |\n|---|---|\n| Recording output folder | Where recorded MP4 files are saved |\n| Record hotkey | The key combination that starts a whole-screen recording (default: `Ctrl+Shift+R`) |\n| Cursor highlight | Show a glowing ring around the cursor during recording; configurable size |\n| Click ripple | Show a ripple effect on mouse clicks during recording |\n| Microphone *(advanced)* | Include microphone audio when recording starts |\n| Microphone device *(advanced)* | Which Windows audio input device to use |\n| GIF export FPS *(advanced)* | Frame rate for GIF exports: 5 / 8 / 10 / 15 / 20 |\n\n### Annotation\n\n| Setting | Description |\n|---|---|\n| Default annotation color | Pre-selected color when the overlay opens |\n| Stroke thickness | Default pen/shape width |\n| Style presets | Up to 5 named color-and-thickness shortcuts shown in the annotation toolbar |\n\n### App\n\n| Setting | Description |\n|---|---|\n| Theme | App appearance: Light, Dark, or System (follows Windows) |\n| Auto-update check interval | How often to check for new releases: Every day / Every 2 days / Every 3 days / Never |\n\n## Keyboard shortcuts\n\n| Shortcut | Action |\n|---|---|\n| `Print Screen` (default, configurable) | Open region-capture overlay |\n| `Ctrl+Shift+R` (default, configurable) | Start whole-screen recording |\n| `Ctrl+Z` | Undo last annotation |\n| `Ctrl+Y` | Redo annotation |\n| `Ctrl+C` | Copy screenshot to clipboard |\n| `Escape` | Close the overlay / cancel current action |\n\n## Requirements\n\n- Windows 10 or later\n- [.NET 10 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/10.0)\n\n## Installation\n\n**Via winget (recommended)**\n\n```powershell\nwinget install DimitarRadenkov.Pointframe\n```\n\n**Manual installer**\n\nDownload the latest installer from the [Releases](https://github.com/dimitar-radenkov/Pointframe/releases) page and run it. During setup you can choose to download `ffmpeg.exe`, which is required for MP4 recording and GIF export.\n\n## Troubleshooting\n\n- **Recording or GIF export does not start** — Pointframe requires `ffmpeg.exe` for MP4 recording and GIF export. If you skipped the ffmpeg download during setup, install `ffmpeg.exe` next to the app, under `Assets\\ffmpeg`, or on `PATH`.\n- **OCR is unavailable** — OCR uses Windows.Media.Ocr and requires a supported Windows build.\n- **Hotkey seems ignored** — Make sure another app is not already using the same key and try changing the capture hotkey in Settings.\n- **App is running but not visible** — Pointframe lives in the system tray after launch.\n\n## Building from source\n\n```powershell\ngit clone https://github.com/dimitar-radenkov/Pointframe.git\ncd Pointframe\n\ndotnet build Pointframe/Pointframe.csproj\ndotnet run   --project Pointframe/Pointframe.csproj\n```\n\n## Running tests\n\n```powershell\ndotnet test Pointframe.Tests/Pointframe.Tests.csproj\n```\n\n## Project structure\n\n```\nPointframe/             Main WPF application\n  App.xaml.cs           DI setup, tray icon, global hotkeys\n  AnnotationTool.cs     Enum of all annotation tool types\n  CountdownWindow       Fullscreen countdown overlay\n  OverlayWindow         Region-selection and annotation UI\n  RecordingOverlayWindow  Live annotation surface during recording\n  ViewModels/           MVVM view models\n  Services/             Screen capture, recording, geometry, update check\n  Models/               Immutable data records and settings\n\nPointframe.Tests/       xUnit test project\n  Services/             Service unit tests\n  ViewModels/           ViewModel unit tests\n```\n\n## Versioning\n\nVersions are managed automatically by [Nerdbank.GitVersioning](https://github.com/dotnet/Nerdbank.GitVersioning).\n\n- The base version (`major.minor`) is declared in [`version.json`](version.json).\n- The patch number is derived from the **commit height** — it increments automatically with every commit, so you never need to touch it manually.\n- On a tagged release (`v*`) the version has no pre-release suffix (e.g. `1.2.5`). On non-release builds a short commit hash is appended (e.g. `1.2.5-g1a2b3c4`).\n\nTo bump the version:\n\n| Goal | Action |\n|---|---|\n| Bug-fix / patch | Nothing — commit height auto-increments |\n| New feature (minor) | Edit `version.json` → `\"version\": \"1.3\"` |\n| Breaking change (major) | Edit `version.json` → `\"version\": \"2.0\"` |\n\n## Tech stack\n\n- **WPF / .NET 10**\n- **CommunityToolkit.Mvvm** — `[ObservableProperty]`, `[RelayCommand]`\n- **Microsoft.Extensions.DependencyInjection** — constructor injection throughout\n- **Serilog** — file + debug logging (`%LOCALAPPDATA%\\Pointframe\\logs\\`)\n- **ffmpeg** — external encoder used for MP4 recording and GIF export\n- **Microsoft.Extensions.Hosting** — Generic Host + `BackgroundService` for the auto-update background loop\n- **Windows.Media.Ocr** — built-in Windows OCR for text extraction\n- **Hardcodet.Wpf.TaskbarNotification** — system tray icon\n- **Nerdbank.GitVersioning** — automatic semantic versioning from git history\n- **xUnit** — unit tests\n- **Azure Monitor / OpenTelemetry** — anonymous usage telemetry (disabled when connection string is absent)\n## 🤝 Contributing\n\nWe welcome contributions! Whether it's reporting a bug, suggesting a feature, or submitting a pull request.\nPointframe is built on a very clean, modern stack (.NET 10, WPF, CommunityToolkit.Mvvm) making it a great jumping-off point for developers.\n\n1. Check out our [Developer Guide](docs/developer-guide.md) and [Architecture Knowledge Base](docs/project-knowledge-base.md).\n2. Browse our [Planned Features](docs/planned-features.md) or look for issues tagged `good first issue`.\n3. Open a Pull Request!\n\n## Privacy \u0026 Telemetry\n\nPointframe collects **anonymous, privacy-safe usage telemetry** in official builds to help understand how the app is used and catch errors early. Screenshots, recordings, OCR output, file names, file paths, exception messages, and stack traces are not sent as telemetry.\n\n### What is collected\n\n| Event | Properties |\n|---|---|\n| `app_started` | `version`, `os_build`, `screen_count` |\n| `startup_completed` | `duration_ms` |\n| `app_heartbeat` | `uptime_minutes` (sent about every 4 hours while the tray app remains open) |\n| `app_closed` | `session_minutes` |\n| `snip_started` | `type` (region / whole_screen), `source` (tray / hotkey) |\n| `snip_cancelled` | `type` (region / whole_screen) |\n| `capture_delay_used` | `delay_seconds` |\n| `capture_completed` | `action` (copy) |\n| `capture_pinned` | — |\n| `open_image_used` | — |\n| `annotation_committed` | `tool` |\n| `recording_started` | `type` (region / whole_screen) |\n| `recording_completed` | `duration_seconds` when available |\n| `ffmpeg_missing` | — |\n| `microphone_unavailable` | — |\n| `gif_export_started` | — |\n| `gif_export_completed` | `success`, `duration_seconds` |\n| `ocr_used` | — |\n| `update_check_manual` | — |\n| `update_available` | `version` |\n| `update_confirmed` | `version` |\n| `update_dismissed` | `version` |\n| `unhandled_exception` | `exception_type`, `context`, `last_action` when available |\n\nEvery event includes an app `version`, a per-run `session_id`, and an `install_id` when one is available. The install ID is a random GUID generated once on first launch and stored locally. It is used only to count unique installs; it is not tied to an account or identity.\n\n**Nothing leaves your machine except these anonymised events.** Screenshots, recordings, OCR output, file names, and file paths are never transmitted. Local diagnostic logs are stored under `%LOCALAPPDATA%\\Pointframe\\logs\\` and may include local paths to help troubleshoot issues; they are not uploaded automatically.\n\n### Source builds\n\nTelemetry is disabled automatically when the `ApplicationInsights:ConnectionString` value in `appsettings.json` is empty (which is the default in the source repository). Only official builds distributed via the installer include the real connection string.\n\n### For contributors\n\nTo enable telemetry locally during development, create `Pointframe/appsettings.Local.json` (gitignored):\n\n```json\n{\n  \"ApplicationInsights\": {\n    \"ConnectionString\": \"\u003cyour-connection-string\u003e\"\n  }\n}\n```\n\nTo set up your own Azure Application Insights resource, follow the [Azure Monitor setup guide](https://learn.microsoft.com/en-us/azure/azure-monitor/app/create-workspace-resource).\n\n\n## Support\n\nIf you find this tool useful, consider buying me a beer 🍺\n\n[![PayPal](https://img.shields.io/badge/PayPal-donate-blue?logo=paypal)](https://paypal.me/DimitarRadenkov)\n[![Revolut](https://img.shields.io/badge/Revolut-donate-black?logo=revolut)](https://revolut.me/dimitarradenkov)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdimitar-radenkov%2Fpointframe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdimitar-radenkov%2Fpointframe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdimitar-radenkov%2Fpointframe/lists"}