惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
博客园_首页
博客园 - 【当耐特】
量子位
S
SegmentFault 最新的问题
B
Blog RSS Feed
酷 壳 – CoolShell
酷 壳 – CoolShell
V
Visual Studio Blog
T
Tailwind CSS Blog
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
Y
Y Combinator Blog
博客园 - 聂微东
The Cloudflare Blog
小众软件
小众软件
J
Java Code Geeks
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
月光博客
月光博客
H
Help Net Security
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
宝玉的分享
宝玉的分享

少数派

派早报:Google 发布 Fitbit Air 等 - 少数派 「新人报到」確認需求,再開始 - 少数派 从 SOLO 独立开发者社区,我看到了越来越多开发者开始做自己的产品 - 少数派 我怎么管理那些"不常做,但总会忘"的生活事项 - 少数派 人形机器人量产元年,数据才是具身智能的“生死线” - 少数派 BuhoLaunchpad 高度还原 Mac 启动台:开发历程与思考 - 少数派 五年陪伴依然不舍,DIY 换壳后让罗技 MX Master 3 继续服役 - 少数派 新玩意 240|少数派的编辑们最近买了啥? - 少数派 一日一技|为什么你应该关闭 iOS 的键盘声音 - 少数派 我做了个插件和 Skills,一键提取任何网站的设计规范 Design.md - 少数派 住在三四线城市的你,该开始录播客了 - 少数派 甘南秘境,大白高国 - 少数派 AI的审美:谁让把我变成川内倫子 - 少数派 返工怎能不烦恼,打工人片单总有一部是你的「嘴替」 - 少数派 为了让「上厕所」更健康,我做了一个小工具 - 少数派 AI + Skill,能够让生成的文章去除 AI 味吗? - 少数派 新玩意|韶音OpenDots ONE 耳夹式耳机 - 少数派 《美满》| 在每一个春天的晚上相爱(362) - 少数派 新玩意|优篮子 PS01 MagSnap 磁吸支架 - 少数派 自我整合手记 | 我开始早睡了:用稳定规则,为自由托底 - 少数派 用龙虾(OpenClaw)两个多月,我最深的12个体会 - 少数派 听歌时间到,12 张你可能错过的 2025 华语乐坛好专辑 - 少数派 承诺能追吗 - 少数派 macOS 26启动台没了? 我做了个不一样的App启动器 - Keboard - 少数派 《四海为家的人》| INTJ对话INTJ(361) - 少数派 你发过的那些黑历史,是时候一次清干净了 - 少数派 新玩意:安安静静玩,越玩越专注:计客密码机 - 少数派 iPad 用户首次体验 Android 平板:vivo Pad6 Pro - 少数派 数据逻辑强 - 少数派 极北行+ | 一路向北,探访日本至北之地 | 001 - 少数派
Tauri跨端笔记实战(4) - 如何实现系统级截图 - 少数派
2025-05-29 · via 少数派

前言

Tauri 跨端笔记实战项目是基于 Notegen 开源项目,本系列深度解析如何运用Tauri框架开发跨平台AI笔记应用。涵盖核心技术选型、架构设计、典型场景开发及常见问题解决方案,通过代码级演示带您掌握集成AI能力的全流程开发技巧。

NoteGen 应用截图:

原理分析

本期主要讲解如何实现一个系统级别的截图功能,这是实现笔记应用中截图记录的功能的前提。整个截图的流程是,通过快捷键或点击按钮进行截图,框选区域实现部分截图,然后根据 OCR 识别进行文字提取,最后保存下文本和截图文件。

要实现屏幕上的截图,仅靠前端是无法实现的,还需要借助 rust 来实现。整个实现原理是,通过 rust 进行屏幕截图,并储存为一张临时图片,通知前端读取图片,在前端实现框选功能,首先需要创建一个新的窗口,然后框选后将选取的范围信息通知给 rust 进行裁切图片,随后保存。

屏幕截图

Rust 实现截图,我使用的是 XCap 库,它支持 Linux(X11,Wayland)、MacOS 与 Windows,所以移动端并不能使用它来实现。XCap 支持截图与视频录制,截图支持屏幕截图、窗口截图,这里我们先实现屏幕截图,窗口截图可以在后期实现更加优秀的截图体验。

src-tauri/src/ 下创建一个 screenshot.rs 文件,用来编写截图程序:

触发屏幕截图时调用 screenshot,它将屏幕进行截图,保存为 BaseDirectory::AppData 目录下的 temp_screenshot.png。屏幕截图时可以注意,获取的是 monitors,这代表可以实现多屏幕截图,这里可以在未来进行优化,我们现在只对主屏幕进行截图。

screenshot_save 则是在前端框选结束后调用的方法,通过 x、y、width、height 进行对 temp_screenshot.png 图片的裁切,保存图片时我才用了时间戳的方式保存,因为这些都是临时文件,不会进行同步工作,所以无需考虑是否会重复的问题。

然后就是在 main.rs 中注册这两个方法,使得前端可以调用:

这样我们就完成了 rust 的代码编写,即使你没有 rust 的开发经验,这些代码也是非常易懂的。

框选截图

拿到屏幕截图后,还需要对其进行框选操作,这里就需要前端来实现了。其原理是创建一个新的 WebviewWindow,使其窗口最大化,然后背景则是读取刚才的截图文件,框选功能可以使用一些现成的库来实现,我使用的是 react-image-crop ,将框选后的结果传递给 rust 即可。

首先要做的是创建一个新的窗口:

const currentWindow = getCurrentWebviewWindow()
await currentWindow.hide()

await invoke('screenshot')
  
const monitor = await currentMonitor();

if (!monitor) return;
  
const webview = new WebviewWindow('screenshot', {
  url: '/screenshot',
  decorations: false,
});

webview.setPosition(monitor?.position)
webview.setSize(monitor?.size)

webview.onCloseRequested(async () => {
  if (!await currentWindow.isVisible()) {
    await currentWindow.show()
  } else {
    await currentWindow.setFocus()
  }
  unlisten()
})

这里进行了几个操作,获取当前显示器的大小和位置,随后创建一个新的窗口,decorations 的意思是创建一个无边框的窗口,然后将当前的应用窗口隐藏,在截图后将应用窗口在展示,这是为了避免截图时被应用的窗口挡住。

首先在 src/app/ 下创建一个新的页面 screenshot/page.tsx :

这里需要注意的是屏幕的物理像素和逻辑像素是不一样的,比如 4k 屏幕的物理像素就很高,而逻辑像素就很低,如果计算错误则会导致选区未知错误,所以需要通过 getCurrentWebviewWindow().scaleFactor() 来进行转换。

截图操作结束后,调用 invoke('screenshot_save', ...) 将结果传递给 rust 进行处理,同时关闭此窗口。

如此我们就实现一次系统级的截图功能,在后续的文章中我讲带大家学习如何对截图进行 OCR 文字提取。

相关链接

Github 仓库:github.com/codexu/note…

官网:notegen.top/