# duckshot **Repository Path**: acomma/duckshot ## Basic Information - **Project Name**: duckshot - **Description**: 各种 Agent + Model 的产物 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-09 - **Last Updated**: 2026-09-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 鸭鸭截图 一个仿 QQ 截图的 Windows 桌面截图工具。常驻系统托盘,无主窗口,通过全局热键或托盘菜单触发。 技术栈:**Windows + WPF + .NET 8**(C# 12)。 图标来源:https://www.magnific.com/icon/viewfinder_9714668 ## 功能特性 - **常驻后台**:系统托盘运行,不占任务栏、无主窗口。 - **全局热键**:默认 `Ctrl+Alt+A` 一键唤起区域截图;热键可在托盘「设置」中自定义并持久化(保存到 `%LOCALAPPDATA%/Duckshot/hotkey.json`)。 - **多屏支持**:物理像素采集 + `PerMonitorV2` DPI 感知;区域 / 窗口 / 自由 / 全屏均按选区所在显示器处理 DPI。混合 DPI 多屏下逻辑↔物理换算仍是整虚拟屏平均近似值(见「已知限制」)。 - **多种截图模式**:区域、窗口、自由(不规则多边形)、滚动长截图(自动 / 手动滚轮)、全屏。 - **标注编辑器**:选择 / 移动 + 9 种标注工具(矩形、椭圆、直线、箭头、画笔、文字、序号、马赛克、橡皮),选中 / 移动 / 缩放,撤销 / 重做。 - **复制与保存**:一键复制到剪贴板(DIB + PNG 双格式)、保存本地 PNG。 - **取色器**:编辑器内调色板 + 吸管像素取色(带放大镜 loupe)。 - **钉在桌面**:把标注图钉在桌面置顶,可拖拽、可关闭、支持多张。 - **托盘常驻**:无主窗口,右键托盘菜单选择截图模式、自定义热键或退出。 明确**不实现**:OCR 屏幕识图、屏幕录制、二维码识别。 ## 截图模式 | 模式 | 说明 | 入口 | |------|------|------| | 区域截图 | 拖拽框选矩形区域;热键触发时若鼠标位于最顶层窗口上则转为窗口截图(高亮 + 左键确认,v4.8),此时按住拖动仍可框选区域、重新框选后亦然(v4.10) | 热键 `Ctrl+Alt+A` / 托盘「区域截图」 | | 窗口截图 | 直接截取当前活动窗口(v4.7);前台无效时退回悬停识别、单击捕获 | 托盘「窗口截图」 | | 自由截图 | 鼠标绘制任意多边形,闭合后裁剪(多边形外透明) | 托盘「自由截图」 | | 滚动长截图 | 框选后进入手动滚动拼接:鼠标滚轮真实滚动内容、停顿自动截帧拼接;滚动期间选区旁浮出功能条(编辑 / 保存 / 取消 / 完成)与实时拼接预览,左键暂停、点「完成」结束、`Esc` 取消(v4.9)。托盘「滚动截图」与标注工具条「滚动截图」走同一条链路 | 托盘「滚动截图」/ 标注工具条「滚动截图」按钮 | | 全屏截图 | 整个虚拟屏幕(所有显示器拼接) | 托盘「全屏截图」 | ## 托盘菜单 右键托盘图标弹出菜单,从上到下依次为: | 条目 | 作用 | |------|------| | 区域截图 | 进入区域截图(等同 `Ctrl+Alt+A`) | | 窗口截图 | 截取当前活动窗口 | | 自由截图 | 进入自由截图 | | 滚动截图 | 进入滚动长截图 | | 全屏截图 | 截取整个虚拟屏幕 | | 设置 | 打开热键设置窗口,自定义全局截图热键并持久化 | | 退出 | 退出程序 | ## 工具条 框选完成后在选区旁浮出工具条,从左到右依次为:标注工具 → 撤销 / 重做 → 吸管 → 滚动截图 → 重新框选 → 钉在桌面 → 保存 → 完成 → 取消。 ### 标注工具 | 工具 | 作用 | |------|------| | 选择/移动 | 点选标注后拖动移动、拖八向手柄缩放;点空白处取消选中 | | 矩形 | 拖拽画矩形框 | | 椭圆 | 拖拽画椭圆框 | | 直线 | 拖拽画直线 | | 箭头 | 拖拽画带箭头的直线 | | 画笔 | 按住拖动自由涂画笔迹 | | 文字 | 点击落点后输入,`Enter` 提交、`Esc` 取消 | | 序号 | 点击生成自增数字圆圈(1、2、3…) | | 马赛克 | 拖动涂抹像素化遮盖,只调块大小、不调颜色 | | 橡皮 | 点击标注即删除,可撤销 | ### 其余按钮 | 按钮 | 作用 | 快捷键 | |------|------|--------| | 撤销 | 回退上一步标注操作 | `Ctrl+Z` | | 重做 | 重做被撤销的操作 | `Ctrl+Y` | | 吸管 | 点击画面取色,应用到当前工具 | — | | 滚动截图 | 把当前选区转入滚动拼接:滚轮向下滚动即逐帧拼接(顶部提示条实时显示拼接高度);滚动期间选区下方浮出功能条——「编辑」转去标注、「保存」存盘、「取消」放弃、「完成」结束,左键在画面上点击为暂停 / 恢复,已产生标注后禁用 | — | | 重新框选 | 丢弃当前标注,回到框选重新截图 | — | | 钉在桌面 | 把成品图置顶钉在桌面,可拖拽、可关闭,支持多张 | — | | 保存 | 存为本地 PNG | `Ctrl+S` | | 完成 | 复制到剪贴板(DIB + PNG 双格式)并结束 | `Enter` / `Ctrl+C` | | 取消 | 放弃本次截图 | `Esc` | ### 其他 - **每个工具独立的颜色与尺寸**:点击工具图标在工具条下方展开该工具的设置面板——8 色调色板 + 尺寸滑块(与数字框联动;矩形 / 椭圆 / 直线 / 箭头 / 画笔为粗细 1-32 像素,文字 / 序号为字号 10-100,马赛克为块大小 1-10 且无颜色行);设置跨截图记忆(托盘常驻期间)。 - 吸管取色应用到当前工具;颜色与尺寸对最近使用的绘制工具生效。 - 选择/移动工具下选中标注后按 `Delete` 删除(可撤销);文字标注回车提交后固化为只读文本,可继续被选中、移动。 ## 技术栈 - **.NET 8** / `net8.0-windows`,C# 12,`Nullable` + `ImplicitUsings` 开启; - **WPF**(未引入 WinForms,多屏枚举等全部走 P/Invoke Win32); - [Microsoft.Extensions.Hosting](https://www.nuget.org/packages/Microsoft.Extensions.Hosting) — DI + 生命周期托管; - [CommunityToolkit.Mvvm](https://www.nuget.org/packages/CommunityToolkit.Mvvm) — `[ObservableProperty]` / `[RelayCommand]` 源生成器; - [H.NotifyIcon.Wpf 2.3.2](https://www.nuget.org/packages/H.NotifyIcon.Wpf/2.3.2) — 系统托盘图标(锁定 2.3.2:2.4.1 起移除 `net8.0-windows` 目标,会触发 `NU1701`)。 ## 快速开始 ### 构建 ```bash dotnet build Duckshot/Duckshot.csproj -c Debug ``` ### 运行 ```bash ./Duckshot/bin/Debug/net8.0-windows/Duckshot.exe ``` 启动后程序常驻托盘。右键托盘图标选择截图模式,或直接按 `Ctrl+Alt+A` 区域截图。 ## 项目结构 ``` Duckshot/ ├── App.xaml(.cs) # 入口:DI Host、托盘菜单、热键注册 ├── app.manifest # PerMonitorV2 DPI 感知 ├── Assets/tray.ico # 托盘图标 ├── Models/ # 截图模式、区域、显示器、标注模型 │ └── Annotations/ # IAnnotation 及 9 种标注实现 ├── Services/ # 截图采集、滚动拼接、剪贴板、文件、热键、编排 ├── State/ # 撤销/重做栈、标注命令 ├── Utils/ # 位图转换、滚动拼接算法 ScrollStitcher ├── ViewModels/ # Tray / Overlay / Editor ├── Views/ # OverlayWindow、滚动截图窗口、PinWindow │ └── Controls/ # AnnotationCanvas(标注交互核心) └── Win32/ # P/Invoke 常量、结构体、方法封装 IconGen/ # 生成 tray.ico 的小工具 ``` ## 已知限制 - 多显示器**混合 DPI** 下,逐屏精确映射仍有既有已知限制(区域/窗口/自由/全屏均已按所选区域所在显示器处理 DPI);滚动截图的取景与窗口命中已按屏幕物理坐标计算,负原点(显示器位于主屏左侧/上方)不再串位。 - 滚动长截图只拼接**向下**滚动(上滚忽略);一次滚过超过选区高度会因无重叠丢帧,此时提示条会显示"未能识别本次滚动,已跳过一次"并自动重锚继续,滚动节奏以"滚动—停顿—再滚动"为宜;平滑滚动需停顿约 0.3 秒后才会截帧;拼接总高上限 20000 px(含倍增容量,不再超额分配)。 - 窗口截图依赖 DWM 合成窗口属性,对个别自绘边框窗口可能识别不准。 ## 许可证 仅供学习交流使用。