eSearch Documentation

截屏 离线OCR 搜索翻译 以图搜图 贴图 录屏 万向滚动截屏 屏幕翻译 Screenshot Offline OCR Search Translate Search for picture Paste the picture on the screen Screen recorder...

RAW Doc

Technical Documentation: xushengfeng/eSearch

ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference

Overview (`README.md`)

eSearch

(中文 | English)





简介

eSearch 是Information-portal的:electron:重写版(顺便加了亿些功能)

主要是想在 Linux 上(win 和 mac 上也能用)实现锤子大爆炸或小米传送门这样的屏幕搜索功能,当然也是一款方便的截屏软件。

经过数次版本迭代,eSearch 的功能愈加丰富

即拥有 截屏+OCR+搜索+翻译+贴图+屏幕翻译+以图搜图+滚动截屏+录屏

字体是FiraCode,字体可在设置里设置

下载安装

到网站eSearch下载

或在右侧 releases 打开标签,选择符合你系统的包并下载安装

国内可以用GitHub 镜像加速下载

ArchLinux 可在 AUR 查找安装 e-search或e-search-git

winget winget install esearch

暂时没有 Homebrew 包,欢迎有志愿的维护者提供支持

启动

在你的启动器打开 eSearch,他将出现在托盘。

默认快捷键为 Alt+C(你也可以在设置里设置快捷键)

功能

更多介绍见文档

截屏

框选裁切、取色器、自由画笔、几何、马赛克、模糊

框选除了通过方向键调节,还支持输入四则运算式调整

支持自定义框选后立马执行操作,如框选后自动 OCR

还支持滚动截屏,横向、竖向、任意方向都可以拼接

截屏美化

可为截屏设置背景(渐变、图片)、圆角、阴影

改变图像分辨率导出

抹除物体并修补图像

录屏

录制屏幕、自定义大小、摄像头

可提示光标位置和键盘击键

可设置虚拟背景

超级录屏

自动缩放聚焦到鼠标位置,录屏更生动

加速、删除,操作每个帧

屏幕贴图

滚轮缩放、透明度、自动归位、鼠标穿透

支持放大图像且不改变窗口大小,防止遮挡其他内容

可通过 CSS 设置滤镜、变换(如镜像)

OCR(文字识别)

开箱即用的离线 OCR(eSearch-OCR,基于PaddleOCR),框选文字后按下回车键即可

大字符集,支持生僻字、特殊符号(需要在设置下载 v5 模型)

离线 OCR 支持段落识别,也可以使用基于标点符号的分段算法

支持竖排文本,支持图片旋转识别

同时也支持百度、有道的在线 OCR

可后期编辑文字,在图片上选择文字,同步选区到编辑区,方便校对

支持多语言:中文、英文、韩文、日文、泰卢固文、卡纳达文、泰米尔文、拉丁文、阿拉伯字母、斯拉夫字母、梵文字母(需要在设置额外下载)

以图搜图

谷歌、百度、Yandex 的以图搜图引擎

可自定义多模态大模型接口,与 AI 交流图片

翻译

OCR 后可调用翻译,支持选词翻译

支持免费的翻译引擎,如谷歌翻译等,也可以自己设置其他翻译引擎的 API,如 DeepL、百度等,可以使用 ChatGPT 等 AI 翻译,甚至可以自定义本地 AI 翻译

可多个引擎同时翻译,择其善者

可以保存翻译结果到本地文件或通过网络保存到 Anki 等记忆软件

屏幕翻译

生成一个贴图窗口,并把图片文字替换成翻译后的文本

可设置定时翻译,适合视频、游戏等

其他

二维码识别

展示

https://user-images.githubusercontent.com/28475549/155870834-34ffa59f-9eac-4eea-9d82-135681d7dfa9.mp4

截屏,自由调整框选大小(视频约 2.6MB)

https://user-images.githubusercontent.com/28475549/155870857-99c7d6d0-a90b-4558-872a-85f2603225d6.mp4

取色器(视频约 1MB)

https://user-images.githubusercontent.com/28475549/155870867-fb0d31f0-2e06-431c-9ae9-ee3af5a5c08e.mp4

Ding 在屏幕上,透明度调节、归位以及鼠标操作(视频约 1.8MB)

绘图界面

https://user-images.githubusercontent.com/28475549/155870881-9b2fc1b3-77de-4a99-8076-ed49b7b5c4c0.mp4

主页面搜索和其他应用编辑(视频约 1.6MB)

主页面查找替换(支持正则)

国际化

大多数按钮使用图标,简少了不必要的翻译

+添加新语言

  • 简体中文
  • 繁体中文
  • 世界语(Esperanto)
  • 西班牙语(Español)
  • 阿拉伯语(عربي)
  • 英语(English)
  • 法语(Français)
  • 俄语(Русский)

源码运行&编译

shell
git clone https://github.com/xushengfeng/eSearch.git
cd eSearch
npm install
# 编译
npm run dist
# 将在build目录产生安装包和解压的目录
shell
# 运行
npm run start
# 调试
npm run dev

具体技术说明

测试

在 ArchLinux,KDE plasma,Xorg 下测试通过

Windows10 和 Windows11 测试通过

macOS Catalina 测试通过

Q&A

不再支持 Win7、Win8

Electron 官方不再支持 Win7、Win8,所以 eSearch 也不再支持。

但可以自己编译,见文档,部分功能可能无法使用。

下载依赖库

大部分 Windows 在安装后会提示下载依赖库,这是因为截屏库需要,点击下载,将自动打开微软官网下载,安装完成后可能需要重启。

Gnome 点击后无响应

Gnome 用户需要安装appindicator插件来使用托盘。

mac 提示文件已损坏

mac 对互联网下载的 dmg 做了部分限制。

可以在互联网上搜索“mac”、“文件损坏”等关键词。不同版本的系统适用的方法也不同。

为什么选择 electron

  • 跨平台需要,本来我是想在 Linux 上也能体验 Windows 下优秀的截屏工具,Linux 独占也不好,所以选择跨平台。
  • qt 依赖 c++,学习成本太高。flutter 桌面版还不太成熟。我更擅长 js 开发。
  • 截屏依赖本地系统,这是目前浏览器做不到的。
  • 最后只有 js 类跨平台方案,我选择了较为成熟,使用最多的 electron。

在其他平台没有类似 Arch Linux 单独打包作为库的情况下,软件占用的存储空间是比较多的,但几十行 js 脚本的增加不多,带来的功能却显著地感知到,所以我会尽力发挥其潜力,做到更精美的 UI、更丰富的功能。

为什么安装包这么大

除了 Electron 的占用,还有 onnx 运行库(用于运行 AI 模型)、离线文字识别模型、录屏人像识别模型、高级编辑的物体移除模型、FFmpeg(用于录屏格式转换,Linux 有库所以不附带)等。

更新版本后出现了以前没有的错误

一般是因为不同版本的配置不兼容,可以尝试在 设置-高级-高级设置 里 恢复默认设置。

若未能解决问题,请提交 issue

贡献

请查看贡献指南

开发原因

我在用 Windows 时一直用这个好用的截屏软件:Snipaste - 截图 + 贴图,但我切换到 Linux,Snipaste 不支持(2019 年,现在已支持),所以我选择了Flameshot,很可惜它没有直观的取色器。

促使我开发 eSearch 的另一个契机是我很享受在手机上使用锤子大爆炸或小米传送门这样的即时信息搜索工具,但我没有找到电脑上类似的代替品。

所以我干脆自己开发一个“截屏+OCR+搜索+贴图”的软件。最开始用 python+pyqt 开发出Information-portal,但因为我不熟悉 pyqt,所以我转战:electron:,开发出本软件。😄

赞赏与支持

精神支持:点亮右上角 star 星标 🌟

物质支持:个人主页赞赏

行动:反馈 bug、提供新功能点子、参与开发

License

GPL-3.0 © xushengfeng


Overview (`lib/readme.md`)

gtk-open-with

https://github.com/timgott/gtk-open-with

gtk license: LGPL-2.1

kde-open-with

https://github.com/xushengfeng/kde-open-with

kde frameworks license:LGPL

win_rect.exe

用于 Windows 下窗口识别

https://github.com/xushengfeng/win_rect

copy.exe

用于 Windows 下的复制(自动搜索和选中搜索需要用到)

https://github.com/xushengfeng/win_rect


Overview (`docs/develop/readme.md`)

开发文档

本文档用于备忘、pr 指引和技术分享


Overview (`docs/use/readme.md`)

欢迎阅读 eSearch 使用文档

Translations
Immersive Translate can help you translate this document into your native language.

你可以进一步了解 eSearch 的功能

你现在看到的版本可能是与软件相适应的版本,如果你想看最新的文档版本(包括开发版甚至是正在开发的未发布的版本),请访问GitHub master 分支。

在这之前,你需要安装 eSearch,如果有运行库按钮提示,请下载并按照提示安装。

由于 eSearch 是电脑软件,你还需要了解电脑操作的基本知识,包括鼠标左中右键的点击、快捷键的使用等。

在使用说明(点击打开)中,你将了解到 eSearch 的基本使用方法,各个功能的具体用法、提示技巧和高级功能。

尽管 eSearch 尽量避免的一些问题并给予提示,但仍有一些常见问题需要给出来参考。

如果遇到操作上的问题,可以在GitHub Discussions进行反馈。如果软件有错误,或者有任何建议,欢迎在GitHub Issues中提出。

[!TIP]

如果你很难访问 GitHub,可以使用Watt Toolkit进行免费的 GitHub 加速,也可以通过Gitee访问本文档的镜像。

[!NOTE]

本人文字水平有限,文档尚未涵盖所有功能,欢迎大家补充。


Overview (`lib/translate/readme.md`)

翻译 Translate

创建 csv,指定存在的语言进行编辑或指定新语言
Create a csv, specify an existing language for editing or specify a new language

[!TIP]
选项-a用于输出全部文字。如果你发现原来的翻译存在不足,需要修改,请使用这一选项。如果你需要跟进翻译,即 eSearch 的某些文字已经修改,但翻译未修改,请不使用这一选项

The option - a is used to output all text. If you find that the original translation is inadequate and need to be modified, please use this option. If you need to follow up on the translation, that is, some text in eSearch has been modified, but the translation has not been modified, please do not use this option

shell
node lib/translate/tool.js -l en
# en.csv
# 或 or
node lib/translate/tool.js -l en -a
csv
"abc","你好世界",""
...

with arg -e,output Chinese with English

csv
"abc","你好世界","Hello World",""
...

编辑 edit

[!TIP]
AI prompt:“以下是 csv 文件,把第二列翻译成 en 并复制到第三列”

csv
"abc","你好世界","Hello World"
...

保存 save:

shell
node lib/translate/tool.js -i en.csv

只有在 source.json 里定义的文字才能被翻译。如果找不到需要翻译的文字,那可能是我没针对某些页面进行国际化,请在 issue 上提交 bug,指明需要国际化位置

Only words defined in source.json can be translated. If you can't find the text that needs to be translated, it may be that I have not internationalized some pages. Please submit bug on issue to indicate the location where you need to be internationalized.

标记翻译进度

tool.js定义了 srcCommit,借助 git 的 diff 功能,来方便地了解需要翻译什么内容。翻译完某个 id 后,将其添加到对应语言的finishId,再次输出 csv 时,将忽略他,这样可以专注与未翻译/修改的翻译。如果全部翻译完,请把 srcCommit 的id改为 latestSrcId,并清空finishId

tool.js defines srcCommit. With the diff feature of git, you can easily understand what needs to be translated. After translating an id, add it to the finishiId of the corresponding language, and ignore it when you output csv again, so that you can focus on the untranslated / modified translation. If you have finished the translation, please change the id of srcCommit to latestSrcId and clear finishiId

开发者

一般地,若 source.json 没有定义语言,在 console 控制台以红色 🟥 字体和背景输出,若未翻译,以蓝色 🟦 字体和背景

In general, if source.json does not have a defined language, it will be output in red 🟥 font and background on the console, and in blue 🟦 font and background if not translated.


Overview (`src/renderer/setting/readme.md`)

创建设置项流程

遵循AGENTS.md前置类型操作

在变量s中添加设置项,返回的el应该使用dkh-ui创建,sv和gv类型匹配设置

有一些常用ui,如xNumber返回设置数值ui,xSwitch是开关,其gv类型兼容boolean,还有如xColor xPath xSecret xFont sortList dialogB。xGroup仅用于排版布局,类似flexbox。

注意元素onchange事件要能触发

然后在main中添加进设置的key

可以通过bind添加修改某些项后触发其他项页面更新,或者bindF触发具体函数。bindF2规定哪些项更新后触发重启app提示等。

如果要获取某个设置项,是用getSet而不是store.get,尽量不设置其他设置项,必要时使用setSet设置

添加、修改、删除文字都要触发AGENTS.md的翻译流程


Develop Overview (`docs/develop/overview.md`)

整体说明

技术选型

使用 Electron 开发。高情商:JS 适合快速开发,低情商:我不擅长 C++和 Rust。

跨平台方案的体积和内存自然是很大,所以我尽量让功能对得上他的体积。tauri 也不错,只能希望以后 Windows 和 macOS 下也有类似 ArchLinux 下 Electron 共享运行时的方案。

使用 Biome 作为格式化和检查工具,使用 vite 作为打包工具。

前端:

使用 TypeScript,很少使用类型体操,仅作为简单的类型标注。主进程开启了 strict 模式,但渲染进程没有,历史遗留问题太多。

框架:

使用自己开发的dkh-ui,只是对 JQuery 的拙劣模仿。我学不会vue和react,搞不懂 hook,ref 这些概念,所以你可以在代码里看到直接使用document和HTML的操作,当然也在逐步转为 dkh。

库:

截屏库: node-screenshots

图片编辑库:fabric.js

本地文字识别:eSearch-OCR,基于onnx和paddleOCR实现。

其他库可以参考package.json文件。

文件说明

electron-builder.config.js electron-builder 配置文件,用于打包
assets 程序图标
src 项目源码

src/main/main.ts 主进程 处理 cli,窗口管理

src/renderer/assets 渲染进程资源,如图标
src/renderer/browser_bg 主页面浏览器错误提示
src/renderer/clip 截屏界面
src/renderer/css 样式文件
src/renderer/ding贴图界面,贴图屏幕翻译
src/renderer/editor 主页面,编辑器,OCR、以图搜图和二维码识别也在此运行
src/renderer/photoEditor 高级图片编辑器
src/renderer/recorder 录屏提示栏、录屏编辑
src/renderer/recorderTip 录屏框选、光标和按键提示
src/renderer/root 初始化样式,保持各个页面的统一
src/renderer/screenShot 简单封装的截屏库,用于 cli 截屏、截屏界面截屏和屏幕翻译截屏
src/renderer/setting 设置界面
src/renderer/translate 主页面翻译,封装了常用 API
src/renderer/translator 实时屏幕翻译
src/renderer/videoEditor 高级录屏编辑器\

src/renderer/capture.html 截屏页面

src/ShareTypes.d.ts 配置类型定义,主进程和渲染进程 ipc 时类型定义,在这种多页面的项目中很方便

lib/store 自己写的设置存储库,参考了electron-store,但直接使用 ts 进行类型定义,不依赖ajv
lib/translate 翻译库,用于多语言国际化

OCR 模型和人像抠图模型在打包或编译时下载,不放在 git 里了,见electron-builder.config.js

其他

图标:

使用 svg 图标,通过 `` 显示。


Develop Clip (`docs/develop/clip.md`)

截屏

使用node-screenshot库,Wayland 平台调用了桌面的截屏软件,再读取图片,所以会有些慢。由于该库暂不支持 Linux Arm64,所以我在 nodejs 下模仿类似的操作,读取设置里的命令,调用外部截屏软件,然后读取图片。

坐标

canvas 坐标与数学上的一致,在左上角的一个像素点应为(0, 0) 1x1的矩形。包括图片的裁切,实际上是 canvas 上的整数矩形坐标。这些整数坐标描述了整数方格的一个个交点。对于框选和获取元素定位来说,这些数学坐标是最重要的。所以理论上,大小栏和鼠标跟随栏的坐标应该是数学坐标,放大镜的中心点应为相交线。

而我们需要的取色器却要获取一个像素点的信息,准确来说,是一个范围,一个 1x1 的矩形,也可以近似为 n.5 的信息,我们可以把他成为像素坐标。在取色器上,此时的坐标又应该是像素坐标,放大镜中间应该是中心像素。

我们可以发现,数学坐标和像素坐标这两个看似矛盾的概念在逻辑上可以相互转化,如果我们以数学坐标(整数,落在像素顶点上)为准,那这个坐标周围的四个像素就可以是取色目标;如果我们以像素坐标为准,那这个像素矩形的四个顶点也表示了四个数学坐标。后一种方式是eSearch的逻辑。然而在开发初期,一直到现在,都要面临鼠标事件的不准确问题。

在 Chrome 126(Linux Wayland)实验可知,鼠标事件的坐标都是整数,应该是经过math.round转换后的数学坐标。比如$(1.5, 2.5)$都被映射成$2$。我们需要的整数数学坐标直接使用鼠标事件的坐标即可。

至于像素坐标,由于鼠标事件无法提供精确的坐标,所以我们似乎无法计算。在画布缩放==1 时,我们可以简单地用鼠标事件坐标表示,可以映射所有像素,肉眼也看不出差别。但缩放!=1 时,特别是>1 时,我们可以看到鼠标所在图片像素的位置,这就需要精准计算了,可以获取鼠标在屏幕上的坐标(offsetX在scale的画布上也近似了),通过缩放转化计算,我们可以获取高精度的数学坐标,通过Math.floor或Math.ceil取整,得到像素坐标。

说完具体实践,我们再说回理论,尽管数学坐标和像素坐标可以相互转化,但他们都有四种情况,如何使用和显示?eSearch像素坐标优先,因为放大后像素本身比像素顶点更明显,鼠标指在像素上,交互也应该是像素坐标才对。在取色、框选等输入交互中使用像素坐标,而代码处理都是使用数学坐标。因此绘制矩形框选需要数学坐标,取框选前后两个像素的外框作为几个数学坐标。

自由框选就不能这么做了,所以直接用像素左上角的数学坐标即可。大小栏不直接参与交互,显示数学坐标即可。鼠标跟随栏上的坐标,同样用像素左上角的数学坐标,这样会导致不从左上角开始的框选显示坐标和框选坐标有出入。

广截屏

即滚动截屏

思路:获取滚动前后位移,拼接

由于我们很难通过系统 API 层面获取滚动的像素,比如一些网页可以监听滚动事件自己设置滚动距离,所以我们通过分析图片来获取滚动距离。

需要至少两张截屏图片,一张滚动前,一张滚动后。使用uiohook-napi获取鼠标滚动事件和方向键,也可以定时截屏。

可以通过特征点算法来分析图片位移,但opencv.js没有提供,所以我只使用了最简单的模板匹配算法。

由实践可知,模板需要小于源图片大小,否则匹配结果不准确,所以我们需要裁切第二张图片。

还要考虑的是一些界面有固定元素,比如导航栏等,我们可以通过异或算法来消除这些固定元素,但在 eSearch 中,我使用了简单的裁切,一般固定元素在图片四周,所以我们自己裁切,大部分情况下效果不错。

举个例子:有“目”字形的页面结构,第 1、3 个“口”可能是固定元素,第 2 可能是滚动元素。我们预期得到一个中间长,上下固定元素均保留的长截屏。我们裁切第 2 作为模板,匹配上一张截屏,得到位移。如果位移向下,把 2、3 覆盖到上一张截屏,这样 1 保留,2 延伸,并覆盖了上一张的 3。其他方向同理,如果考虑上下左右滚动的广截屏,以九宫格来切割。


Develop Ding (`docs/develop/ding.md`)

贴图

贴图需要置于顶层、可缩放、可移动、可调节透明度、可鼠标穿透,还需要管理其他贴图(取消穿透的贴图)。

首先自然想到使用BrowserWindow暂时每一张贴图,但在缩放时网页反应不及时,透明窗口在 Windows 下无法调节大小。

所以我们只能考虑通过 web 绘制每一张贴图的窗口(不考虑额外语言或技术的实现)。

我们需要创建一个透明的全屏置顶窗口,通过主进程发送的图片和坐标(来自截屏)来绘制每一张贴图。

为了模拟窗口效果,我们只允许贴图接收鼠标事件,无贴图的位置鼠标穿透。见主进程-透明窗口


Develop Main (`docs/develop/main.md`)

主进程

异形窗口

electron 讨论

贴图、广截屏、屏幕翻译都使用了异形透明窗口,部分区域接收鼠标和键盘事件,其他区域只负责显示。

通过screen.getCursorScreenPoint()获取鼠标位置,通过减去窗口位置,计算出相对位置,把相对位置发送到渲染进程。

渲染进程根据相对位置,通过elementFromPoint(s)()获取鼠标所在元素,这里可以通过 js 判断是否为可点击元素,再把boolean发送给主进程,主进程根据boolean设置鼠标穿透setIgnoreMouseEvents。

然而 macOS 和 Wayland 不支持在窗口外获取鼠标位置,当窗口鼠标穿透时就再也无法获取鼠标位置了。广截屏操作不多,使用了全局快捷键代替鼠标点击,其他的暂时没有解决方案。

运行目录

根据编译出来的 js 文件深度,可以通过path.join(__dirname, 向上目录深度)获取你想要的运行目录,eSearch编译的目录为eSearch/out/main/main.js和eSearch/out/renderer/*.html,定义的runPath为join(__dirname, '../../')也就是项目目录。

需要注意eSearch不使用 asar 打包,app.isPackaged时的__dirname应该有所不同,具体请自己实验。

系统语言

一般可以通过app.getLocale()获取当前语言。然而,为了减小打包体积,eSearch移除了locales目录,而app.getLocale()依赖于locales目录。更好的方法是app.getPreferredSystemLanguages(),这是真正的获取系统语言的 api。


Develop Ocr (`docs/develop/ocr.md`)

OCR

使用 PaddleOCR 实现文字识别。为了在 web(Electron)上使用,需要把 PaddleOCR 的 Python 代码转换为 JavaScript,同时把模型转换为ONNX格式。

原本打算使用 Paddle.js,但当时支持有限,所以代码是直接从 Python 中翻译过来的,一边调试一边学习,解码部分参考了 Paddle.js 的实现。后来 LLM 横空出世,一些图片处理功能在以前没来得及实现的都使用 AI 翻译了。

PaddleOCR 分析

基于 v3 版本,尽管现在的模型是 v4。

文字识别分为文字检测(rec)和文字识别(det)(目前不考虑方向、排版等)。

文字检测获取文字坐标(Paddle 里按行),裁切后送入文字识别模型。

文字检测

结果是二值图,每个像素点为 0 或 1,代表是否有文字。通过 opencv 查找轮廓,确定边框。

文字识别

输入是裁切后的图像,输出数组的一级是按字的数组,二级是字典索引对应的概率。字典一字一行,行号-1 是每个字的索引。输出的概率列中,对应了每个字与图片中文字的相似程度,找到概率最大的索引,对应的文字就是结果文字。

排版分析

使用模型进行排版识别的成本有点高,我打算用算法来分析。

文字检测输出的矩形坐标比较精细,像一行里的话,模型会把空格隔开的小段文字视为一个矩形区域。

我们先把这些小片段合并成一行,再合并成一段。

合并为行

一开始的算法是把 y 坐标相近(偏差不超过平均高度 50%)的小片段合并在一起,这种算法在大部分情况下运行良好,但遇到左右分栏的文本,会粗暴地跨栏合并,毕竟他们 y 坐标确实是相近的。

通过分析,我们知道分栏的间距一般都会比句子空格大,或用线条或颜色分隔开。现在只考虑间距问题。

我们把矩形按行分类,y 相差不大(0.5 高度)且直接间距小于高度的合一起。

分栏

上面的操作已经隐式分栏了,同一 y 坐标存在不同的 x 坐标,意味着属于不同栏。

模拟人阅读方式,从左上开始,遍历 y 坐标。找出中心最近的矩形,通过一定规则的过滤(左、中、右至少有一个大致对齐),判断是添加到已有的栏还是新建栏。

合并为段

有两种分段方式:通过空行和通过行首空格。

空行分段同样可以使用间距分析,直接统计间距频度,以下是一个真实数据:

json
{
  "-3": 2,
  "-2": 1,
  "0": 4,
  "1": 4,
  "2": 4,
  "3": 3,
  "4": 4,
  "5": 5,
  "7": 1,
  "8": 1,
  "9": 1,
  "10": 1,
  "13": 1
}

我们注意到 5-7 的位置应该是我们需要分段的间距:大于等于 7 的间距都是段间距,其他是行间距。取导数绝对值最大的即可。我还提升他们使其大于 0,并去掉最大频率的数来减少极端数据的影响。


Develop PhotoEditor (`docs/develop/photoEditor.md`)

高级图片编辑器

渐变

归纳CSS 渐变,可以分为线性(linear)渐变、径向(radial)渐变、锥形(conic)渐变和他们的重复渐变。

Canvas API 渐变的实现,可以参考MDN CanvasGradient,但更多参数,颜色断点仅支持百分比。

我们的渐变不需要太多功能,参数就只是中心位置、角度、重复和颜色断点。

线性渐变

参考MDN linear-gradient(),需要注意线性轴的位置,对应ctx.createLinearGradient

为了保证边角也应用渐变,不是裁切或填充,需要对轴进行计算,MDN 上有一副图示:

由于是线性,我们可以在轴的垂直方向平移轴以方便计算。

角度(angle)与一般数学上的定义不同,从-y 到+x,我们先不管这么多,现在只需要计算轴长,具体坐标才考虑角度。图中角假设为锐角。

起始坐标为$(0,h)$,终止坐标为$(\sin(a),h-\cos(a))$


Develop Start (`docs/develop/start.md`)

开始

准备工作

  • vscode
  • npm
  • node.js
  • git

大陆用户为了方便访问 GitHub,可以使用Watt Toolkit进行免费的 GitHub 加速。

建议使用pnpm作为包管理工具,同时设置镜像源为 npmmirror.com:

shell
pnpm config set registry https://registry.npmmirror.com/

设置 Electron 的镜像源:

shell
pnpm config set electron_mirror https://npmmirror.com/mirrors/electron/

克隆项目到本地:

shell
git clone https://github.com/xushengfeng/eSearch.git
# 如果不需要代码回溯
git clone --depth=1 https://github.com/xushengfeng/eSearch.git

使用 vscode 打开eSearch文件夹,安装依赖:

shell
pnpm install

[!TIP]
如果不需要 cuda,或者网络问题,可以设置环境变量 ONNXRUNTIME_NODE_INSTALL_CUDA="skip"

运行与编译

运行:

shell
pnpm run start

由于我还没配置好 vite 下调试带有.node的库,所以无法使用pnpm run dev。

打包:

shell
pnpm run pack

编译:

shell
pnpm run dist

打包后的文件位于build文件夹下,已经有可执行文件,编译则生成安装包。


Develop SuperRecorder (`docs/develop/superRecorder.md`)

超级录屏

通过记录鼠标的坐标和点击,自动运镜。

核心是视频裁切。使用 FFmpeg 是自然的选择,wasm 太慢,录屏(旧)的裁剪是通过命令控制 FFmpeg 二进制来实现的。

观察 Electron(Chrome)的运行目录,我们可以发现有一个ffmpeg.dll或libffmpeg.so库,用于浏览器的媒体解码和渲染。浏览器有的,我们就不需要额外引入 FFmpeg 了,现在有一个新的 web api:WebCodecs,可以调用浏览器的媒体解码编码能力。

在这之前,我先说明媒体编码的重要性,如果我们用连续截屏的方式代替录屏,虽然 ImageData 可以很方便地进行图片截取,但内存会被迅速占用:

单帧全彩色高清(1920x1080)视频(每像素 4 字节)为 8,294,400 字节。

在典型的每秒 30 帧的情况下,每秒高清视频将占用 248,832,000 字节(~249 MB)。

一分钟的高清视频需要 14.93 GB 的存储空间。

视频编码其实就是一个压缩过程,把相同像素合并,还有其他高级的压缩操作。这样,我们借助视频编码压缩存储帧,编辑时解码成 ctx,编辑后再次编码压缩,导出时也使用了编码。

WebCodecs

具体请见MDN、chrome dev 博客、w3c等文档,或者学习WebAV这个项目,由于这个 API 复杂且新,网络上的文档不多,我也在学习中,下面是我的部分总结。

这里主要使用VideoDecoder和VideoEncoder,通过new确定回调(类似reader之类的 api),然后必须configure。使用时调用各自的decode和encode即可。

VideoFrame是原始帧数据,需要及时close。

flush方法可以理解为 Promise onend之类的方法,需要注意的是,for循环后用flush能正常等待完成操作,但其他异步的循环会提前结束(与其是结束,其实的处理队列暂时为空),所以要确保异步循环完毕再flush。

close也要注意调用。

GOP,指一个关键帧到下一个关键帧前的所有帧序列。

大部分编码模式在解码时除了必要的关键帧,还要前面的所有帧(对于一个 GOP 来说),所以,对于不是连续获取帧的操作(也就是除了播放),我们需要flush,并重新解码一遍。

ts
await decoder.flush();
for (let i = keyFrameIndex; i <= thisIndex; i++) {
  decoder.decode(chunks[i]);
}
await decoder.flush();

转换(编辑)

我们处理一个视频,需要解码(解压缩)->编辑处理->编码(压缩)

ts
const decoder = new VideoDecoder({
  output: (frame: VideoFrame) => {
    // 解码 处理 编码
    const nFrame = transformX(frame);
    encoder.encode(nFrame);
    nFrame.close();
  },
  error: (e) => console.error("Decode error:", e),
});

decoder解码后再编码,output可以视为异步循环,所以要注意flush的调用问题。

ts
for (const chunk of src) {
  decoder.decode(chunk);
}
await decoder.flush();
await encoder.flush();

这里先对decoder flush,因为 decode 用的是for同步循环,确保把所有任务都放到 encode 处理队列后,再对encoder进行flush。不能交换两者顺序,否则导致提前结束,代码提交 944a8a0就是解决这个 bug 的。

为了防止一下子往处理队列里加入太多数据导致卡顿,在 decode 循环中可以提取flush:

ts
for (const chunk of src) {
  if (chunk.type === "key") {
    await decoder.flush();
    await encoder.flush();
  }
  decoder.decode(chunk);
}
await decoder.flush();
await encoder.flush();

如果 encode 和 decode 的关键帧索引不同,理论上会错位,但 encoder 即使 flush 也能正确编码,似乎 flush 不会清空相关的帧,而 decoder 在 flush 后需要重新传入 keyFrame。在规范中 decoder 有key chunk required这一说法,但 encode 确实没有,也没有规定。

优化

处理视频的成本很高,所以我们需要进行优化。

注意到我们的编辑(如改变运镜)只会影响一部分的帧,其他帧的画面是不变的,所以我们可以考虑复用数据。这是从看得见的画面上考虑。我们还有考虑编码中的复用情况。考虑到帧依赖前面的帧,所以某个帧变化,在 GOP 中其后面的所有帧都要改变。解编码时需要前面的帧。索引,一个 GOP 里面的帧变化,整个 GOP 都要重新渲染,但这比所有帧重新渲染性能高很多。

在 eSearch 中,存储了原始录屏数据,同时存储了每个帧的操作,比如裁切的矩形。然后我们对比每个帧的操作,得到变化的帧。再填充变化帧所属的 GOP 帧索引,只需要重新渲染他们就可以了。这有点像前端的虚拟 DOM。

由于我们只需要处理部分帧,所以需要帧的标识,在 eSearch 中使用的是时间戳。变速操作最后再改变时间戳。

删除帧也是可以优化的。比如某个 GOP 后面全是要删除的帧,那他们就不会被这个 GOP 里的帧所依赖,我们在解码时就可以直接忽略他们。

视频数据十分容易膨胀,所以我们要关注内存,分析是否有未回收的数据。

打包

我们平时接触的视频格式:mp4、webm 等记录了不止视频,还有帧率、声音、甚至字幕等信息。他们被成为容器。

不同容器支持的视频格式也不同,参考mdn

浏览器并没有提供容器包装器,只提供了编码器,所以我们需要其他的库,如 mp4box.js,我使用 mp4-muxer 和 wemb-muxer。

音频

超级录屏的声音(麦克风、系统内录)走 WebCodecs 的 AudioEncoder 编码为 opus,编辑时按时间轴解码成 PCM 并跟随删除/变速重排,预览用 Web Audio 播放,导出时经 mediabunny 的 AudioBufferSource 混入容器。采集时钟与视频时间戳的对齐方式、模块划分、已知限制见超级录屏 · 录音功能计划。


Develop SuperRecorderAudio (`docs/develop/superRecorderAudio.md`)

超级录屏 · 录音功能计划

超级录屏 目前只录画面(videoEditor.ts 中 getUserMedia 的 audio: false),本文档记录为它添加录音(麦克风 + 系统内录)的调研结论、设计方案、实施顺序和后续优化点。

状态:实施顺序 1~9 已全部完成并分批提交;「已知限制 & 后续优化」「测试要点」中的条目为后续跟进项(勾选框未勾即待办)。回归验证见 test/superRecorderAudioE2E.mjs。

目标

  1. 录制:可选麦克风(可多选)、可选系统内录,录制面板可控、可看音量电平。
  2. 播放:预览播放器(canvas + WebCodecs 手写播放器)播放时同步出声,播放/暂停/跳转跟随。
  3. 导出:mp4、webm 导出时带上音频;gif/apng/png 天然无音频。
  4. 编辑:音频跟随已有时间轴编辑(删除、变速),保证音画不错位。

调研结论

  • 超级录屏全在 src/renderer/videoEditor/videoEditor.ts(单文件):
    • 采集:getUserMedia({ audio: false, video: {chromeMediaSource:"desktop"} }) → MediaStreamTrackProcessor → VideoEncoder → 内存中的 EncodedVideoChunk[](录制期不落盘)。
    • 编辑:uiData{clipList,speed,eventList,remove} → getFrameXs() 得到逐帧 FrameX → runTransform() 只重编码变化帧。
    • 播放:无 <video>,canvas + play()/pause()/jump2id() 手写播放器,时间轴 timeLineTrack 工厂。
    • 导出:mediabunny(Output + EncodedVideoPacketSource + BufferTarget),不走 ffmpeg。
  • 录屏(旧) src/renderer/recorder/recorder.ts 已有可借鉴的音频实现:
    • 麦克风:enumerateDevices() 过滤 audioinput,getUserMedia({audio:{deviceId}}),选择结果持久化到 录屏.音频.设备列表("00" 表示系统音频)。
    • 系统内录:getUserMedia({ audio: {mandatory:{chromeMediaSource:"desktop"}}, video: {...} }) 与视频同一调用(受 录屏.音频.启用系统内录 门控,注释说明可能导致应用崩溃)。
  • mediabunny 1.14.3 已具备所需能力:Output.addAudioTrack、AudioBufferSource(PCM 直接进封装器,内部用 WebCodecs 编码)、EncodedAudioPacketSource、getFirstEncodableAudioCodec、format.getSupportedCodecs()。
  • 全仓库此前没有任何 AudioContext / AudioEncoder 使用,音频链路需全新实现。
  • 设置项:复用 录屏.音频.设备列表、录屏.音频.启用系统内录(录屏(旧)已在用,语义通用),不需要新增设置项。

设计

数据流

text
麦克风 track ─┐                                    ┌─ opus EncodedAudioChunk[](录制结果,≈1MB/min)
系统内录 track ─┼→ AudioContext(混音/增益) → MediaStreamTrackProcessor
              │        └ 每路 GainNode:勾选=1,取消=0(取消后只写入静音,不保留原始声音)
              └→ AudioEncoder(opus) ───────────────┘
                                   ↓ 停止录制后(按需解码,用完即弃)
                        AudioDecoder → 源时间轴 PCM (AudioBuffer)
                                   ↓ buildTransAudio(frameXs)
                  OfflineAudioContext 调度(删除区间不排、变速段 time-stretch)
                                   ↓
                变换后 PCM (AudioBuffer) ─┬→ 预览播放 AudioBufferSourceNode
                                          └→ 导出 mediabunny AudioBufferSource

关键决策

  1. 编码存 opus,不存 PCM:录音 48k 立体声 float PCM ≈ 23MB/min,opus 128kbps ≈ 1MB/min。录制期只留编码 chunk;PCM 只在「变换/播放/导出」时按需解码,且源 PCM 在生成变换结果后即释放,稳态内存 ≈ 1MB/min(源) + 23MB/min(变换结果)。
  2. 时钟对齐:视频帧时间戳与音频 AudioData 时间戳(尤其经 AudioContext 处理后)可能不在同一纪元。统一用 performance.now() 作参考:
    • 录制中持续累计 vOff = min(videoTs - perfNow*1000)、aOff = min(audioTs - perfNow*1000)(µs);
    • 停止时求出换算常量 originUs = aOff + firstVideoTs - vOff(firstVideoTs 为首个视频帧原始时间戳);
    • 每个音频 chunk 的最终时间 = (ts - originUs) / 1000(ms,相对视频第 0 帧,负值丢弃)。
    • 误差 = 两路各自的最小采集延迟之差,经验值约 10~30ms,已标记为后续优化点。
  3. 混音走 AudioContext:每路 createMediaStreamSource → GainNode → destination,勾选/取消用增益开关(不中断混音输出,时间轴连续);音量电平取混音 PCM 的 RMS。单路也走同一路径,保证只有一条代码路径。
    • 系统内录的 track 若未在录制开始时取得(默认不请求,保持现有行为不变),中途勾选时补一次 getUserMedia({audio, video});其视频轨保留到录制结束(中途停止可能连带停掉同一会话的音频),失败则回退并提示。
  4. opus 参数自适应:编码 sampleRate/numberOfChannels 取第一帧 AudioData;若采样率不在 opus 支持集(8/12/16/24/48k,如 44100)则转 48000,声道 >2 则降混为 2。转换统一输出 f32-planar。
  5. 编辑跟随 getFrameXs 的时间线:变换段由 frameXs 推导 —— 段起点 = frameXs[i].timestamp(输出时间轴),源区间 = [srcCs.getTime(i), srcCs.getTime(i+1)),输出时长 = frameXs[i+1].timestamp - frameXs[i].timestamp;被删除帧不产出段。
    • 变速:timeStretch(WSOLA)把段落源音频拉伸到输出时长且保持音高,再与删除区间一起排进 OfflineAudioContext,startRendering() 一次渲染完成。
  6. 导出:saveWebm/saveMp4 中 format.getSupportedCodecs() ∩ 候选列表(mp4: aac→mp3→opus;webm: opus→vorbis)→ getFirstEncodableAudioCodec → output.addAudioTrack(new AudioBufferSource({codec, bitrate})),在视频包之后 await audioSource.add(transPcm)。取不到可编码音频 codec 时退化为无音频并在界面提示。
  7. 播放:播放/暂停/结束时用 AudioBufferSourceNode 启停,offset 取 transformCs.getTime(playI),与现有 resetPlayTime() 的媒体时间一致;时钟同源(单调钟),不额外做漂移校正。

文件改动清单

文件 内容
src/renderer/videoEditor/audio.ts(新增) 采集 AudioCapture(混音/增益/编码/电平/时钟偏移)、解码 decodeSrcAudio、变换 buildTransAudio
src/renderer/videoEditor/videoEditor.ts IIFE 内接入采集与停止、帧循环上报时间戳、录制面板音频控件(设备勾选/系统内录/电平条)、runTransform 尾部构建变换音频、playEl/pause/playEnd 挂预览音频播放、saveWebm/saveMp4 加音轨
lib/translate/source.json 新增文案 id(node lib/translate/tool.js -u)
docs/use/record.md 去掉「超级录屏不支持录制声音」
docs/develop/superRecorder.md 增加音频一节,链接本文档

实施顺序(对应提交,格式:超级录屏 xxx)

  1. 超级录屏 录音功能实现计划 —— 本文档。
  2. 超级录屏 录制采集音频 —— audio.ts 采集 + 编码 + 时钟偏移,接入录制 IIFE 与停止流程。
  3. 超级录屏 录制面板音频控制 —— 设备勾选、系统内录开关、实时音量电平,持久化 录屏.音频.设备列表。
  4. 超级录屏 音频跟随时间轴编辑 —— 解码源 PCM、buildTransAudio(删除/变速)、接入 runTransform。
  5. 超级录屏 预览播放声音 —— 播放/暂停/结束/跳转同步。
  6. 超级录屏 导出视频包含音频 —— mp4/webm 加音轨 + codec 回退 + 未包含提示。
  7. 超级录屏 播放前等待转场同步 —— 修复预览播放与 afterTrans() 中 playDecoder.flush() 的竞态(端到端测试中稳定复现,会让预览卡死)。
  8. 超级录屏 音频分段合并优化 —— 相邻同速帧合并成段,避免逐帧建几十万个节点。
  9. 超级录屏 音频功能文档与端到端测试 —— 使用文档、设计文档、test/superRecorderAudioE2E.mjs。

每个提交都跑 pnpm run format、pnpm run typecheck、pnpm run lint。

端到端测试

test/superRecorderAudioE2E.mjs 用 CDP 驱动打包后的真实应用自动跑完整链路(fake 音频设备,不需要麦克风):

shell
pnpm run build
node test/superRecorderAudioE2E.mjs   # 全部通过 exit 0,有失败 exit 1

脚本会自建临时 userData、清理上次残留的 Electron(含被中断的运行)、启动时占用的调试端口冲突会先被清掉;结束或被中断时都会回收整个 Electron 进程组,不会留下孤儿进程。

已知限制 & 后续优化

  • 变速会变调:已实现 timeStretch(WSOLA,见 audio.ts)time-stretch,加速/减速都保持音高。AudioBufferSourceNode 没有 preservesPitch(Chromium 152 实测,只有 HTMLMediaElement 有),Web Audio 也没有别的可用 API,只能自己实现。
  • 变速段接缝精度:分析帧在输出内按 1:1 推进,段尾的源内容位置与相邻段起点最多差一个分析步长(≈10~20ms)。已有越界保护(取下一段源音频,缺失时下一段淡入)避免尾部塌陷与爆音,但瞬态处仍可能听出拼接痕迹。
  • A/V 对齐精度:目前依赖两路最小延迟差(约 10~30ms)。后续可在录制首帧时做一次音频脉冲校准,或直接统一使用采集时间戳纪元(需实测 Chrome 各平台行为)。
  • 时间轴音轨可视化:波形/静音区间显示(可用 timeLineTrack 工厂或独立 canvas 层),并支持单段静音。
  • 单独导出音频(m4a/opus/wav)。
  • mp4 音频优先 AAC:Linux 上 WebCodecs 通常不能编 AAC,会回退 opus(部分播放器不认),后续可考虑接入 ffmpeg 兜底(已有录屏(旧)的 ffmpeg 打包链路)。
  • 录制面板之外的录制前配置:目前设备选择在设置(持久化)与录制面板(实时)两处,若要「点开即选」,需给超级录屏加一个录制确认页。
  • 内存预算:encodeSize 只统计视频,音频(≈1MB/min + 变换 PCM)未纳入停止/告警计算。

测试要点

已由 test/superRecorderAudioE2E.mjs(CDP 驱动真实构建 + Chromium fake 音频设备)验证:

  • 录制面板出现、麦克风按钮展开设备列表、勾选设备、实时电平、选择持久化到 录屏.音频.设备列表。
  • 只麦克风录制出 opus 音频,预览播放创建 AudioBufferSourceNode 并从当前媒体时间出声。
  • mp4、webm 导出均含 opus 音轨,ffprobe 时长与视频一致、频谱与源信号(440/660/880Hz)比例一致(无采样率/音高错误)。
  • 没有任何音频输入时,录制、变换、导出与原行为一致(不回归)。

待人工验证(需要真实硬件/系统内录):

  • 系统内录(真实 loopback,含 启用系统内录 关闭时面板置灰提示)。
  • 录制中取消已勾选设备:设备释放(系统隐私指示灯熄灭)、后续文件时长正确。
  • 删除区间、变速区间后音画同步(变速段落有声且时长与画面一致,快放/慢放人声均不变调)。
  • 变速段与相邻段的接缝处无爆音、无明显拼接痕迹(含接删除区间时的淡入)。
  • 暂停/上一帧/下一帧/时间轴跳转后声音位置正确;播放到结尾停止。
  • 双麦克风混音;无音频输入设备时的提示文案。
  • gif/apng/png 导出不受影响;取消录制后设备释放。

Use Ai (`docs/use/ai.md`)

在线 AI 模型

用于编辑 OCR 校对、AI 以图搜图、翻译、在线 OCR 等

本地 LLM

你可以使用任何技术栈部署 LLM,但需要兼容 OpenAI 的 API。下面以 ollama 为例。

你需要在ollama 官网下载并安装 ollama,添加模型。

在在线AI中添加,填入 url:http://localhost:11434/v1,点击获取模型列表,选择你想要的模型。确保测试通过。

其他免费 LLM 服务

SiliconCloud,需要注册

url: https://api.siliconflow.cn/v1

GPT_API_free,需要 GitHub 账号绑定

url: https://api.chatanywhere.tech/v1


Use Clip (`docs/use/clip.md`)

截屏

截屏界面

为了文档描述方便,我们给截屏界面上的元素起一些名字。一般左边有两条竖直下来的白色元素,上面有很多按钮,左边那条称为工具栏,右边那条称为编辑栏,光标悬浮在编辑栏上,会自动弹出副编辑栏,一直跟着光标的是跟随栏,顶部是大小栏。

工具栏的按钮点击后会触发相应的功能,并一般会关闭截屏界面。

编辑栏(主编辑栏)按钮除了悬浮展开副编辑栏外,直接点击,也可以自动点击副编辑栏的记忆的按钮。比如我上次使用了 形状-矩形、滤镜-马赛克,那么现在点击“形状”按钮,会自动点击副编辑栏的“矩形”按钮,点击“滤镜”按钮等于点击“马赛克”按钮。这样极大地提高了效率。

选区

默认设置下,与截屏前显示一样的、鲜艳的色彩区域为选区,选区外则是灰暗的。初始截屏默认全屏选区,这意味着选中了整个屏幕,屏幕没有灰暗处。

按住并拖动鼠标左键,可以选中一个区域。

光标位于选区边缘或选区中间时,光标会改变形状,提示可以拖动。你可以像窗口一样,可以通过拖动改变选区大小、位置,也可以通过方向键改变。

自动框选

当你光标在某个窗口上时,它会提示框选该窗口,点击即可框选。如果启用了记忆框选,将不启用自动框选。

按s重新框选,无论是否启用记忆框选。

[!TIP]

按住Shift键并进行框选,将匹配合适的窗口框选

自由选择

在编辑栏第一个按钮“选择与操作”切换到自由选择即可绘制任何形状的选区。这个选区只能移动,不能改变。

[!TIP]

全屏时可以新建框选,在选区外可以新建选区。所以如果你想要一个比已有选区更小的选区,可以通过Ctrl+A改为全屏选区,然后再新建一个小的选区。

大小栏

大小栏位于选区上方。分别以像素为单位显示

选区左上角 x 坐标, 选区左上角 y 坐标 选区右下角 x 坐标, 选区右下角 y 坐标 选区长 × 选区宽

等数字。

大小栏的数字可编辑,光标点击你想更改的数字,改变后按下回车键 ↵,即可把数字应用到选区。注意部分数字会随其他数字的改变而改变。

鼠标栏

鼠标栏一直跟随着光标,从上到下依次显示放大镜、坐标、颜色代码。

放大镜

放大镜是由若干色块组成的色彩阵,反映了光标位置下屏幕放大后的效果,每个色块都有与之对应的屏幕像素。处于正中间的色块是光标对应屏幕所在位置,他的坐标显示在下面的坐标区。

若色块有灰色边框,整体偏暗,还有些透明,说明它对应的屏幕像素在选区外。

通过放大镜,你可以清除知道光标所在位置,可以更精确进行操作。

颜色代码

展示了光标所在像素的颜色代码,不同的代码格式可以在设置中选择,目前支持:hex、rgb、hsl、hsv、hwb、 lab、Oklab、lch、Oklch 和 cmyk 格式的代码。

更多

右击,鼠标栏将收起放大器,展开颜色代码(所有格式代码,可点击复制),显示选区大小。再次右击可收起。

工具栏

展示主要功能按钮。

工具栏会在完成选区框选后自动移动到选区旁。

移动

按住Ctrl,即可通过拖动改变工具栏位置。

图像编辑

元素

元素包括笔迹、形状、文字、滤镜等。点击或通过光标拖拉以此选中元素。元素(除了滤镜)被选中后可拖动中间部分来移动,或拖动八个方向的拖块来改变大小,还可以拖动最顶部的拖块来旋转。所有元素都可以通过按下Delete 键来删除。

自由绘画

有画笔、橡皮和喷刷。画笔阴影可以为笔迹添加阴影,使画笔拥有荧光笔性质。

形状

线条、圆和矩形

像框选选区一样,选择相应形状后,按下左键并拖动,以此添加形状。

折线和多边形

选择形状后,在你想要的起始位置点击,然后依次点击下一个点来画线,最后在终点双击即可结束画图。多边形会自动闭合形状,例如五边形你只需画四条线。

文字

在你想要的位置点击即可生成文本框。双击编辑文本。

滤镜

选择滤镜,拖拉出矩形滤镜区域即可添加。部分滤镜可调节风格程度,如马赛克大小等。

颜色和大小

通过点击第一个按钮,可以切换填充颜色和边框颜色设置。线条、箭头等只能更改边框颜色。

上面为颜色输入框,支持输入 CSS 颜色,下半部分可调节不透明度。

色盘

点击颜色,颜色将适用到颜色代码区聚焦位置。原先的不透明度将重设为 100%。右击该颜色,色盘将显示相同色系的更多颜色。再次右击回到主色盘。

层次

选择形状、文字、滤镜等元素后,可通过按钮改变他们的层叠顺序。注意,选择元素后,他在视觉上会自动移动到最顶层,实际位置以不选中元素时的位置为准。

操作

支持撤销、重做、复制和删除四种操作,复制和删除只针对画布上的元素。撤销和重做针对画布和框选。

复制

相当于电脑中的“复制(拷贝)+粘贴”或 macOS 系统中的“复制”。将会生成画布元素的副本在旁边,你可以在设置调节副本相对蓝本的位置。

删除

选中元素后,进行删除,把他们移除画布。

按钮选项

你可以在文字识别、以图搜图、录屏、屏幕翻译和广截屏按钮右上角看到一个小圆点,右键点击按钮或点击小圆点展开更多选项。

文字识别和以图搜图可以更改引擎。

广截屏可以选择长截屏还是广截屏,文档有他们之间区别的介绍。

录屏可选择普通录屏、超级录屏或录屏(旧) 录屏文档。

屏幕翻译可选择实时翻译或贴图翻译 屏幕翻译文档。

框选后默认操作

框选后,我们手动点击功能按钮来使用相应的功能。我们也可以定义框选后默认执行的操作,比如文字识别,这样在框选后就自动执行了文字识别功能。默认执行的操作对应的按钮使用强调色提示,按下鼠标中键可以取消默认操作。

画布导航

通过鼠标滚轮或触摸板滚动,可移动画布。

按住 Ctrl 键并滚动,可缩放画布。

可通过方向键移动画布一像素,按Ctrl可实现 5 倍移动,按Shift可实现 10 倍移动,可叠加速度。

尽管限制了画布的移动范围,使他不会超出窗口,但有时候还是会找不到画布,按Ctrl + 0 还原画布大小和位置。


技巧:

拖动条

拖动条用来调节画笔大小、线条粗细、颜色透明度、滤镜值等,你可以在相关位置看到他们。

与一些其他的拖动条不同,它不支持点击来设置值,这样会导致值的突变,并且拖动条比较小,点击也不精确。

所以拖动条值的变化与鼠标拖动水平位移有关,拖动条的范围被映射到 200px 范围内,你可以在很大的一个控件精确地调节拖动条的值。

点击拖动条,你可以直接通过输入数字来改变值。

在一些位置,右键拖动条可以恢复到上一个设置值。

设置 PrintScreen 为截屏快捷键

本设置针对 win11 用户。

在 系统设置-辅助功能-键盘 中关闭“使用 PrintScreen 捕获屏幕”,再在软件快捷键中设置即可。

--

高级功能:

基于视觉的自动框选

进行图像边缘识别,视觉上重要的选区(图标、文字、导航栏等)可能被识别。需要在设置里开启。

高级设置中的最小阈值和最大阈值是边缘识别算法的参数,你若觉得自动框选不准确,并有相关的知识,可以进行修改。参考

工具栏自动移动方式

展示内容优先

例如:若工具栏将要移动选区左侧,但超出了屏幕,他会移动到选区右侧。若右侧也超出了屏幕,工具栏只能在工具栏左侧内。这种模式最大程度保证工具栏不会遮挡选区,但有可能光标要跨过一个选区点击按钮,效率不高。

效率优先

例如:若工具栏将要移动选区左侧,但超出了屏幕,他会移动到选区左侧内,尽管遮挡了选区内容。这种模式保证工具栏尽可能靠近光标,便于提升效率,但它遮挡了选区内容。

临时隐藏工具栏

可启用 设置-工具栏-稍后显示,这样截屏时不显示工具栏,第一次框选后才显示。

撤销

时间线模式撤销

任何编辑历史都不会在撤销或重做过程丢失,而是以时间为顺序记录当前状态。下面的字母只是比喻。

假设你的编辑过程 A => AB => ABC
撤销 A => AB => ABC
在“AB”基础上编辑,如添加D A => AB => ABC => AB => ABD

撤销&重做

撤销是恢复到当下之前的状态,可以看成回到过去。重做是在撤销后恢复到之后的状态,可以看成回到现在。

假设你的编辑过程 A => AB => ABC
撤销 A => AB => ABC
再次撤销 A => AB => ABC
重做 A => AB => ABC

外部截屏器

用于解决部分 Linux glibc 版本过低或截屏库不支持 arm64 架构问题

为了使用截屏功能,需要在 设置-高级 设置截屏命令

shell
flameshot full -p /dev/shm/esearch-img.png

或

shell
scrot /dev/shm/esearch-img.png

你可以使用 flameshot 或桌面环境的截屏工具,将截屏保存到/dev/shm/esearch-img.png(你也可以设置其他位置),eSearch会自动识别并打开。

既然都用 flameshot,那用 eSearch 岂不是画蛇添足?虽然 eSearch 在一些方面还比不过 flameshot,但在取色器、OCR 校对、广截屏、搜索翻译等方面我用得还是挺顺手的,建议选择适合自己的工具。

托盘截屏样式

部分系统托盘菜单关闭时会有延时。这会影响截屏内容。

在设置源文件中,把主搜索功能.截屏搜索延迟改为其他数字(毫秒)


Use Ding (`docs/use/ding.md`)

贴图

选取的区域变成一个窗口放在屏幕上。

鼠标在贴图上通过滚轮滚动可进行缩放。鼠标放在窗口上,顶部弹出工具栏。

可以改变窗口透明度和大小,可以再次编辑、最小化、归位和关闭。

归位

归位可以让窗口回到最开始位置和大小,于原来截屏位置贴合以至于无法察觉。

悬浮条 鼠标穿透

在屏幕左上角会常驻竖向条形的提示条,点击它,可以展开控制栏,进行贴图窗口最小化还原或关闭。

还可以控制贴图鼠标穿透,使贴图成为一个在屏幕上的图案,无法与鼠标交互,在一些情况下很有用。


实际上贴图“窗口”都是模拟出来的,你可以在系统的一些视图发现有一个全屏的窗口覆盖在屏幕上,显示多个贴图窗口,其他地方透明。

[!NOTE]

macOS 和 Wayland 似乎不支持获取软件外鼠标位置,这导致了贴图无法点击。
可以在配置文件中 贴图 强制鼠标穿透 添加快捷键,手动设置贴图是否可点击。这是全屏范围的,如果你想点击其他界面,需要再次使用快捷键

裁切放大

通过滚轮可以缩放窗口大小,但有时候我们需要放大来看清贴图,但一起放大的窗口会遮挡住我们的视线,如何只放大图片而不改变窗口大小呢?

按Ctrl+鼠标滚轮,就可以做到。

变换

在设置中添加变换,可通过数字键切换不同的变换效果。

变换使用 CSS,你可以在mdn transform或mdn filter了解更多信息。

常见变换(可直接复制到设置):

效果 css
水平翻转 transform: rotateY(180deg)
竖直翻转 transform: rotateX(180deg)
灰度 filter: grayscale(100%)
反色 filter: invert(100%)

[!NOTE]

filter 函数可以传入 svg 滤镜,包括柏林噪音、转置滤镜等你可以在互联网上获取更多资料


Use Editor (`docs/use/editor.md`)

主页面

主要是编辑器,也有浏览功能。

搜索和翻译

按下按钮,eSearch将对全文进行相应的搜索或翻译操作。如果不想搜索或翻译全文,可以用鼠标选区部分文字,这样可以搜索或翻译部分文字。

编辑栏

选中时,文字旁边弹出一个编辑栏。

你可以进行打开链接、搜索、翻译等操作。

自动删除换行

见 OCR 校对

历史记录

点击历史记录,可以查看之前在主页面的文字记录。手动编辑后的文字不会自动保存到历史记录,除非你按下保存到历史记录按钮。

搜索窗口

搜索窗口是eSearch自带的一个简单的浏览器,在主页面上生成。

若设置了浏览器中打开,搜索的链接将在系统默认的浏览器打开,否则,将在搜索窗口打开。

标签页管理

在标签页中打开链接,他可能在新标签页中打开。当标签页过多时,他们不会变短,而是让整个标签页区域可滚动。虽然标签页是横向滚动的,但你仍可以直接用鼠标纵向滚动。

标签页可使用关闭按钮、鼠标中键或鼠标右键关闭,关闭后将展示左边的标签页。所有标签页关闭后,搜索窗口将关闭。

保存到历史记录

搜索窗口不支持历史记录。如果你搜索到重要的内容,可以点击添加到历史记录,此时浏览的标签页网址将保存到主要历史记录,可在主页面查看。

浏览器打开

即使你打开了搜索窗口,你仍然可以通过浏览器打开按钮在浏览器打开当前标签页的网址。在设置中勾选是否在浏览器打开后自动关闭标签页。

图片区

显示 OCR 输入的图片。

清空后,图片区还可以上传其他图片进行 OCR 识别,支持多张图片。

图片区还用于辅助 OCR 校对。

可以在设置里设置 OCR 文字行数超过一定值自动显示图片区。

拼写检查

拼写检查面板可以通过传统的算法检查拼写错误,也可以通过 AI 来检查。可用于 OCR 校对。

AI 检查需要在设置中添加在线 AI。见AI文档

随着文字的修改,拼写提示列表也会更新。AI 检查需要手动重新检查。

鼠标放在列表项目上,编辑区会跳转并高亮可能错误的地方,图片区也跳转到相应的区域并高亮。软件会猜测多种可能的正确拼写,并给出预览,点击应用。如果没有合适的拼写,点击即可跳转到原文,可手动修改。

不是所有的建议都是符合原文,如果给出的建议与图片不符,忽略这些建议即可。

当然,在拼写检查时,你可以放心编辑文字的任何区域,拼写检查会自动识别。拼写检查可撤回。

页面模式

主页面可以有搜索模式和翻译模式,搜索模式下通过 OCR 等识别的结果自动搜索显示,翻译模式下也同样自动翻译显示。

默认是自动模式,单行文字根据英文占比进行搜索或翻译,多行显示编辑器,不进行额外操作。

页面模式可以在托盘设置,也可以在cli指定。

简洁模式

在顶栏点击简洁模式按钮,可以隐藏主页面的工具栏,只显示编辑区。

进行网页浏览时,只保留顶栏。

失焦关闭

若不勾选顶栏的固定按钮,则eSearch将在失去焦点后自动关闭,实现即用即走的效果。

窗口置顶

在顶栏点击置顶按钮,可以将主页面置顶,始终显示在最前面,类似贴图。


编辑技巧:

双击文本,选中词语,三击选中整行。

选择一段文字,除了按住鼠标拖动外,还可以按住Shift,点击,即可选择。

这些技巧不仅仅适用于编辑器,在其他文本(设置中)和其他软件(浏览器、Word)中也同样适用,可以在此文档界面试试。


高级功能:

简洁标签管理

可设置标签为图标模式,只显示图标,不显示标题和关闭按钮。

可设置标签图标为灰度模式,更协调。


Use Long Clip (`docs/use/long_clip.md`)

广截屏

即滚动截屏。无尽的信息超出的屏幕,因而诞生了滚动,为了捕获他们,也有了广截屏。

之所以起名为广截屏,是因为它不仅支持纵向滚动,还支持横向滚动,甚至组合起来,支持万向滚动。

点击广截屏按钮,截屏立即开始。你需要通过鼠标滚轮或方向键手动缓慢滚动页面。只要周围还有空间,软件可以实时预览滚动拼接效果。点击右下角的红点,结束截屏。此时编辑界面会弹出。

[!TIP]

你可以在按钮右上角选择仅仅纵向滚动(长截屏)还是万向滚动(广截屏),一般普通的页面长截屏就够用了。

长截屏拼接率更高。

[!TIP]

为了更好地拼接,框选区域不要太小,框选内容尽量独特,重复的元素不要太多。

滚动速度不要太快,拼接效果会更好。

[!TIP]

Shift+🖱 滚轮 可以横向滚动页面。

[!NOTE]

在特定的操作系统或桌面环境下,广截屏可能出现问题,比如 macOS 和 Wayland 无法识别滚动和结束截屏。

设置里提供了一个选项,可以设置为定时截屏拼接,以及通过快捷键结束截屏。


Use Main (`docs/use/main.md`)

软件主体

eSearch 并不像其他软件一样有一个主要窗口,比如音乐软件就有一个主要的音乐播放窗口。

你最常使用的应该是截屏窗口,框选屏幕内容。而文字识别又会打开另一个窗口,我一般称他为主页面,你也可以叫他编辑器,不管怎样,我们都知道这是用来编辑文字的。还有录屏窗口、贴图窗口、屏幕翻译窗口、高级图片编辑窗口和设置窗口。这些窗口可能有小窗口,可能不止一个,但这不是我们在使用时说关心的,我们只需要知道 eSearch 功能丰富,基本一个功能有一个窗口界面。而这些窗口基本可以在截屏窗口中打开。

你运行eSearch时,除了弹出的通知提醒程序已运行,在托盘(一般在桌面右下角或右上角,看时间的地方)处会显示一个图标。你可以右键点击它,进行图片搜索、打开设置或退出程序。

除了通过托盘截屏,你还可以通过快捷键(默认是Alt+C或⌥C)打开截屏窗口。

自动搜索

当你选中一段文字时,eSearch 在主页面打开这个文字。如果没有选中文字,eSearch 会打开截屏。

Wayland
Wayland 环境下无法获取选中文字,在KDE下甚至会造成按键锁定,见 https://github.com/xushengfeng/eSearch/issues/248#issuecomment-2236211435"> GitHub issue


下面是复杂用法,一般很少接触。

cli

eSearch 提供了一个命令行界面,你可以在命令行中输入命令来执行一些操作。Linux 和 macOS 都可以直接在命令行运行e-search(如果没有,请尝试esearch),Windows 需要定义环境变量才可以在 powershell 中运行。

--加上命令表示表示命令名,-表示缩写,我会把他们写在一起,两者等效,有的命令无缩写。参数可以这样表示:-t Hello``-t "Hello World"或-t="Hello World"。

-h,--help(帮助),-v,--version(版本),--config(打开配置文件),--dev(调试模式/开发者模式)

如:
e-search --help或e-search -v

可以在不打开截屏界面的情况下使用部分功能,这时可以指定图片位置,否则自动截取全屏。

通过-i,--input指定图片位置(可选)。

--delay指定截屏延迟时间(毫秒)

保存

-s,--save保存到路径或剪贴板。

后面可以跟-p,--path指定保存路径,--clipboard保存到剪贴板。

如果不指定路径,依次尝试快速截屏位置、上次保存位置。文件名在设置中指定。

不会自动创建路径中不存在的文件夹。

如:

shell
e-search --save --path /path/to/save
e-search -s --clipboard
e-search --save --path /path/to/save --delay 500

后面可跟-n,指定连拍次数。--dt指定间隔时间,单位为毫秒,默认 100 毫秒。

如:

shell
# 连拍 3 次,间隔 500 毫秒,保存到 /path/to/save/默认文件名 文件夹中,文件名用序号表示
e-search --save --path /path/to/save -n 3 --dt 500

文字识别

-o,--ocr

后面可跟--engine指定引擎。

可跟--search或--trans指定打开主页面时进行搜索还是翻译。不指定时自动判断。

如:

shell
e-search --ocr --engine 默认 --trans

以图搜图

-m,--img

后面参数同文字识别。

贴图

-d,--ding

在光标位置贴图。

打开主页面并显示文字

-t,--text

可指定--search或--trans。

如:

shell
e-search --text="Hello World" --trans

框选后默认操作

见截屏

这些操作不仅可以设置为默认,还可以通过快捷键设置临时操作。

默认情况下,按下Alt+C打开截屏窗口,我们手动框选,手动点击功能按钮。

设置好快捷键后,比如我设置复制为Alt+X,按下快捷键后,框选,自动复制。

在 设置-快捷键 中设置,注意与截屏界面功能快捷键的区别。截屏功能快捷键在截屏界面显示后才使用(比如Alt+C打开窗口、框选、Ctrl+C复制),框选后默认操作快捷键全局生效,一步到位(直接Alt+X,复制)。他们都在 设置-快捷键 中设置,请小心区分。

便携版(绿色版)

eSearch 还有便携版,可以把它安装到 U 盘,不需要安装到系统。

下载对应平台的压缩包版本,此时已经可以运行软件了,但配置仍保存在系统中。我们需要的绿色版配置应该保存在下载的文件夹中。

可以使用自定义配置目录,见配置。把配置目录设置为相对路径,如./config。

在设置中的配置目录,提供了一个按钮,可以把软件直接转为便携版。背后的操作是在运行目录下创建portable文件夹,这样软件就自动使用该目录作为配置目录。自定义配置目录的优先级更高。


版本说明

eSearch 版本号使用点.分隔,分别表示大版本、中版本、小版本,点不具有数学意义,你可以把他看成逗号。版本号更大的功能更多。

版本比较规则
从大版本到小版本依次比较。相等时,继续比较下一位。

14.x.x>13.x.x

14.11.x>14.9.x

14.11.2>14.11.1

大版本(n.x.x):有很多功能添加,一些操作方式优化,底层框架可能升级。这是相对于上一个大版本来说的,相当于中版本和小版本的累积更新。

中版本(x.n.x):小功能添加和优化

小版本(x.x.n):问题修复,可能会伴随一些功能的更新

开发测试版(x.x.x-beta):测试版,可能有一些功能缺失,可能有一些 bug,不建议使用

原始代码编译:需要按照开发指南编译,是最新的版本,与我现在开发的版本一致。

大版本 2 周左右(也许吧,有时短有时长)发布,中版本一周左右发布,小版本由于是用来修复问题,所以发现特别大的问题后会在几天内发布。

如果我因为备考或其他原因暂停代码开发,代码超过一周没有更新,也会发布一个新版本。所以最新发布的版本和最新代码间隔一周左右。

你可以在设置调节软件更新频率:更新大版本、更新中小版本、更新开发版和手动检查更新。

上面的信息仅供参考,具体更新内容、频率以实际为准。

尝鲜功能

有一些功能正在开发中,属于半成品,为了不让他影响到正常使用,我把他们隐藏起来,有一些在截屏工具栏隐藏,你需要在设置中把他拖到显示区,有一些需要在设置中打开“开发者模式”才显示。

开发者模式会弹出控制台,提示可能出现的错误。


Use Ocr (`docs/use/ocr.md`)

文字识别(OCR)

eSearch提供了开箱即用的离线 OCR,还可以选择在线 OCR。

离线 OCR

离线 OCR 完全免费,不依赖网络,但它体积较大。部分在线 OCR 可以免费体验,但它速度快,准确率高,不占体积。eSearch默认启用离线 OCR,可以直接使用。

在线 OCR

eSearch目前支持的在线 OCR 服务是百度 OCR、有道 OCR和大模型OCR。部分使用OCR的功能可能只能使用离线OCR。

百度 OCR

参考百度 OCR 的教程,获取 API Key 和 Secret Key,并填入设置中。截止 2022 年 1 月,百度 OCR 还可以免费领取服务。

有道 OCR

参考有道 AI 文档,在创建应用时服务选择光学字符识别服务-通用文字识别,接入方式为API,获取应用 ID 和密钥,并填入设置中。

大模型OCR

添加支持视觉的AI模型见文档即可

格式

一些 OCR 并不能识别文字,而是把文字的一行视为一个段落。

text
比如这是一个段落。但
由于显示软件的自动换
行,视觉上显示为多行,
OCR把他们视为5个段
落。

自动删除换行

自动删除换行可以分析结尾符号,自动删除换行。你也可以选中部分文字,针对他们进行删除换行操作。支持拉丁文字删除换行后自动添加空格。

段落识别

自带的离线可以识别基本分栏和段落,在设置中可勾选是否开启。设置百度 OCR 的段落识别也可以实现段落分析。

在编辑区按下撤回快捷键可恢复到原始未识别段落的排版。

校对

一方面,现在的 OCR 模型尽管识别率差强人意,但细节上有待提高,另一方面,由于印刷、字体等问题,OCR 常误判。对于一般的文本识别,目前的离线 OCR 已经够用,但如果你需要通过 OCR 录入文字,或精益求精,校对功能是必不可少的。

[!NOTE]

本软件的校对功能并非专业,如果你需要更专业的校对,请使用其他专业 OCR 软件。

同样不对校对结果负责,人是最后的校对者,软件仅作为辅助。

原图校对

仅仅是换行校对还不够,主页面提供了图片区进行辅助校对。

直接在图片区上选择文字,你可以体验类似苹果 Live Text(实况文本)的功能。但不止选择文字,选区将同步到编辑器,你在图片上选什么,编辑器就选什么,这样既可以知道图片上文字的位置,又可以编辑文字进行校对。

编辑器将使用 Chrome 的拼写检查,使用蓝色波浪线标出拼写错误,这样你就可以知道 OCR 这里识别错误(有时候会识别英式英语的一些拼写错误,忽略即可)。只知道错误还不行,需要找出原文,在编辑器上选择文字,自动在图片区上选中原文。

这样的选择双向同步既能了解文字在图片中的信息,也拥有的编辑能力。

不必担心编辑后就无法同步选择了,通过 diff 算法,即使你在编辑器上增删,双向同步也能尽可能地进行定位。


高级功能

其他语言离线 OCR,自定义 OCR 模型

离线 OCR 使用了 paddleOCR 的 OCR 方案。

目前 paddleOCR 还预训练了多种文字识别模型:

  • 中英混合
  • 中文繁体
  • 英文
  • 韩文
  • 日文
  • 泰卢固文
  • 卡纳达文
  • 泰米尔文
  • 拉丁文
  • 阿拉伯字母
  • 斯拉夫字母
  • 梵文字母

你可以直接在设置里下载,那里提供了文字与语言的对应,比如德语对应拉丁文。下载后自动添加到 OCR 模型列表。

也可以在这里下载,都提供了语言到文字的对应,还可以在 GitHub下载,模型都是一样的,GitHub 上没有文字提示。下载完毕后,解压到文件夹里,你会看到 1~3 个文件。打开 设置-OCR 添加模型,文件名有det的为检测模型,部分语言不附带,留空将使用默认模型。文件名有rec的为识别模型。.txt为字典文件。之后你可以更改 OCR 名字。

自己训练:

  • 使用 paddleocr 训练模型
  • 使用Paddle2ONNX本地转换
  • 根据上面的方式添加

AI 后端

默认使用 CPU 运行模型,还支持 WebGPU CUDA(linux)、coreML(mac)、DirectML(Windows)。理论上如果你的设置支持以上三种后端,应该可以更快运行模型。部分模型或设备不支持一些后端,如有错误,请改回 CPU 后端。

目前模型在 CPU 运行时也保持在可接受的速度。


[!TIP]

有时候复制 PDF 文字也会遇到多余的换行,可以尝试使用自动删除换行,不仅仅是用于 OCR 校对。

[!TIP]

你可以设置 OCR 后自动复制文字到剪贴板。


Use Qa (`docs/use/qa.md`)

常见问题

反馈&建议

在github提交反馈

兼容性

由于 eSearch 框架使用 Electron,将不再支持 Win7、Win8

但仍然可以运行在 Win10、MacOS、Linux 等平台上。

最后支持 Win7 等的版本为 1.12.4,但支持 OCR 的版本是 1.8.0

可以自己编译 eSearch ,把一些库降级,并且还能使用新版本的功能(当然肯定不完整了)

降级的库有:

text
electron -> 22.3.27
onnxruntime-node -> 1.12.0或更低版本

编辑package.json文件,找到dependencies和devDependencies下的electron和onnxruntime-node,更改版本号,然后运行pnpm install命令重新安装依赖。


Use Record (`docs/use/record.md`)

录屏

普通录屏

在截屏窗口框选录制区域,选择普通录屏即按该选区的位置和大小录制。它使用超级录屏的录制引擎,但不分析镜头移动,录制结束后仍可在编辑器中调整区域。

录制开始后,选区上会显示录屏提示层:虚线框、键盘和鼠标提示、摄像头画面(均可在设置-录屏-提示中开关),右下角悬浮条显示录制时间和停止按钮。

录制结束后进入与超级录屏相同的编辑界面,可裁剪、变速、导出 Gif、mp4、webm 等格式。

超级录屏

超级录屏提供了自动运镜功能,可以自动聚焦鼠标所在位置。用于教程、计算机操作演示。

录制时会显示录制面板,点击麦克风按钮可选择音频输入:可多选麦克风,也可选择系统内录(需先在设置中开启),右侧电平条实时显示当前音量。音频选择会被记住,下次录制直接生效。

考虑到性能,默认最大只支持录制 5 分钟,可以在设置中修改。

录制结束后,编辑窗口全屏展示。从上往下为播放器、播放器控制器、预览轴、运镜轴、帧轴、导出。

播放器可以以帧跳转播放。帧轴也可以跳转帧。删除、变速等编辑会同步作用于声音,播放器播放时会同步出声。

[TIP]

在当前帧下,可使用截屏打开,进行编辑、保存等操作。

当然,不会影响录屏内容,因为录屏编辑器不是专业的视频编辑器。

可导出为 Gif、mp4、webm 等格式,其中 mp4、webm 会带上录制的声音(Gif、apng、png 不含声音)。

运镜轴

运镜轴由 4 条轴组成,从上到下分别吗镜头轴、速度轴、事件轴和移除轴。

运镜轴按帧均匀显示,而不是时间,所以可能与预览轴播放指示有错位。

双击镜头轴空白位置可新建关键点。

在速度轴、事件轴和移除轴上拖动,可创建关键区间,可以移动和改变他们的大小。右键删除区间。

镜头位置

点击镜头关键点,可以编辑。

拖动框选可改变镜头聚焦位置,通过滚轮缩放可改变大小(变焦)。

镜头的改变有过渡时间和过渡动画,可改变过渡完成的帧,可设置过渡的时间。

结束后可保存。

导航

点击预览轴、运镜轴顶部、帧轴都可以跳转。

点击<和>按钮可跳转 1 帧,按住Ctrl可跳转 10 帧,按住Shift可跳转 100 帧。

点击<<和>>按钮可跳转 1 秒,按住Ctrl可跳转 10 秒,按住Shift可跳转 60 秒。

帧轴

显示当前暂停帧附近的几个帧预览。在下面提示该帧的时间、对应播放序列的编号(从 0 开始)。如果删除了某些帧,后面的帧还会提示对应未删除前的编号(也就是运镜轴的编号)。

录屏(旧)

旧版录屏,用于录制长视频,比如会议、游戏等。

在弹出的控制面板,可以点击红色按钮开始录制。

在控制面板,你可以勾选录音设备(如系统内录或麦克风)来控制音频输入。

可以在控制面板开启摄像头。

控制面板录制后显示停止录制按钮、录制时间和放弃录制按钮。

你可以在录制条上查看录制时间,可以执行停止录制和暂停操作。

有时候你不想你的录制环境出镜,这时候可以使用虚拟背景。通过 AI 技术替换背景,你可以选择不显示背景、模糊背景或使用图片和视频替换。当然最好的方式是在一个独立的摄像头录制环境(比如一面白墙),虚拟背景更多是一种娱乐性质的功能。

录制结束,可修改首尾时间来裁切录屏。

选择保存位置,等待视频处理操作完成。


Use Save (`docs/use/save.md`)

保存

截屏、录屏、贴图支持保存。

保存需要你选择保存地址,开启快速保存后,保存到上次保存的位置。

截屏可保存为 PNG、JPG、WebP 和 SVG 格式。

贴图只能保存为 PNG 格式。

录屏可保存为 mp4、webm、gif、mkv、mov、avi、ts、mpeg、flv 等包装器格式。

SVG 格式是一种可编辑矢量格式,但保存到文件里的截屏是栅格格式,只有图像编辑产生的形状(除了滤镜外)是矢量格式,便于后期修改。

[!IMPORTANT]

SVG 时可编辑的,所以会保留图片原始信息,裁切和形状遮挡等可以后期去除,小心不要泄露隐私。

可通过**eSearch**打开一些图片

安装eSearch后,可以在文件管理器 PNG、JPG、WebP、SVG 等图片右键选择打开方式中使用eSearch打开。请放心,eSearch 不会修改为默认图片打开方式,如果遇到了,请反馈错误。


Use Search (`docs/use/search.md`)

图片识别

提供了 Google、百度、Yandex 的以图搜图功能。

提供一个很简单的 AI 交互界面,可以与 AI 大模型进行对话。


Use Setting (`docs/use/setting.md`)

设置

更改设置后,左下角会显示操作历史。如果误触,或者想放弃本次设置修改,你可以通过点击列表项目撤销。


高级功能

源文件配置

设置使用 JSON 格式进行配置,你可以在设置里打开源文件进行编辑。关于 JSON,你需要注意英文符号、双引号、逗号的使用。最好使用 VSCode 等编辑器进行编辑,它有语法检查、自动完成等方便功能。错误格式的 JSON 会导致程序恢复默认设置。

自定义配置目录

默认配置存储在appData目录下,在不同平台中:

  • Windows: %AppData%/eSearch
  • macOS: ~/Library/Application Support/eSearch
  • Linux: ~/.config/eSearch

你可以在设置里设置自定义配置目录,这个选项是配置的配置,会自动生成preload_config保存在运行目录下。支持相对路径和绝对路径。

如果你想要便携版,保存配置到运行目录,可以参考另一篇文档。


Use Start (`docs/use/start.md`)

快速开始

运行eSearch。按下 Alt+C 或 ⌥C 即可进行截屏。当然也可以右键点击托盘处的图标,点击“截屏搜索”进行截屏。

此时默认框选全屏。

按下鼠标并拖动,画出框,即可框选你想要的区域。

鼠标旁边有一个“工具栏”,你可以点击按钮进行各种操作:

文字识别

图片识别

扫描二维码

其他应用打开

固定在屏幕上

录屏

广截屏

屏幕翻译

高级图像编辑

复制图片到剪贴板

保存

按取消截屏搜索

进行文字识别、以图搜图
或扫描二维码后,产生的文字信息将在主页面展示。你可以在主页面进行各种文字编辑,并进行搜索和 翻译。

除了工具栏,你还会注意到其他栏,这些可以在截屏查看。

应用托盘、后台等说明,请见软件主体。

设置

点击蓝色超链接,由更详细的使用说明。


Use Super Editor (`docs/use/super_editor.md`)

高级图片编辑器

[!IMPORTANT]

该功能目前处于测试阶段,可能存在一些问题,可以在 设置-工具栏 中添加该按钮以使用。

高级图片编辑在截屏编辑之后,无法再回退到截屏的编辑,属于最终加工。

它在原先图片的基础上向外添加一些装饰。

圆角

为图片添加圆角。

外圆角用于整个图片,计算方式为内圆角加上 XY 边距小的那个。

纯色背景

使用 CSS 颜色值,不填写则为透明。

渐变背景

可以使用线性渐变、径向渐变、圆锥渐变。

基本参数为起始位置、角度、颜色值。

位置仅径向渐变和圆锥渐变支持,使用 0~1 表示比例坐标,左上角为(0,0),右下角为(1,1),中间为(0.5,0.5)。

角度仅线性渐变和圆锥渐变支持,使用 0~360 表示角度值。角度均从竖直向上顺时针方向计算(与时钟方向一致)。线性渐变的角度值表示渐变的方向,圆锥渐变的角度值表示起始角度。

[!TIP]

关于这些渐变,你可以查看 CSS 渐变 了解更多信息。语法上他们并不相同,需要注意。

图片背景

图片显示方式为居中填充。

配置

按+号记住当前配置作为模板预设,之后可以直接从列表中选择应用。


Use Translate (`docs/use/translate.md`)

翻译

包括屏幕翻译和主页面的翻译。

软件可以通过各大翻译平台的 API 来实现翻译功能,大部分翻译引擎需要提供 Key(密钥)等信息才能使用,设置中提供了相关链接,你在添加翻译器时可以看到,大部分需要付费才能使用,下面也会介绍一些免费的用法。

[!IMPORTANT]

请注意,翻译引擎的准确度和翻译质量都取决于翻译平台的质量,请根据自己的需求选择合适的翻译平台。
翻译的结果仅供参考,本软件提供的翻译功能仅供学习交流使用,软件作者不对翻译结果负责。

在设置添加翻译器,在弹出的对话框里为翻译器命名(可重名,可不填)、选择翻译引擎类型,并根据链接指引在第三方平台创建 API,填入对话框。

点击测试,若提示测试通过,则可以完成添加。

如果填写的信息有所缺失,则无法点击完成。

可以添加同种翻译引擎的不同翻译器。

主页面翻译将显示翻译器名称。

可在设置调节翻译器顺序,第一个翻译器将作为屏幕翻译的翻译引擎,主页面翻译的多个翻译器显示也根据设置的顺序。

目前无法在屏幕翻译直接设置翻译语言,需要在设置中设置目标语言,一般已经自动设置为软件显示语言。

主页面翻译

你可以使用搜索引擎的方式进行翻译。自定义翻译引擎搜索 URL,翻译时打开在线翻译页面,自动填入文字翻译。

一些翻译URL

Google, https://translate.google.com/?op=translate&text=%s
Deepl, https://www.deepl.com/translator#any/any/%s
金山词霸, http://www.iciba.com/word?w=%s
百度, https://fanyi.baidu.com/#auto/auto/%s
腾讯, https://fanyi.qq.com/?text=%s

这些翻译需要打开他们的网站,页面大部分不简洁,因此eSearch提供了自定义翻译 API 的方式。

主页面翻译引擎列表里已经添加名为翻译的翻译引擎,你可以在设置中更改名字,调节顺序。

这个引擎可以打开软件内置翻译界面,通过读取设置好的翻译器,同时启用多个翻译器进行并行翻译。你可以方便地进行对照,并一键复制。

屏幕翻译

屏幕翻译将自动识别屏幕区域的文字,并翻译成目标语言。

适合科研图片、视频或游戏翻译。

在截屏工具栏按钮右上角可以切换屏幕翻译模式:贴图或自动翻译。

对于一些图片,除了需要翻译文字,还要同时关注图标原本的形状、结构等,可以使用贴图模式。就像贴图一样,生成一个覆盖在原图上的窗口,同时把文字也翻译了。

贴图翻译拥有和贴图一样的功能:缩放、保存、复制等,区别是把图片的文字翻译了。

而对于需要不停翻译的地方,如视频或游戏,可以使用自动翻译模式,定时截取屏幕并翻译。


高级技巧:

生词本

设置生词本,在主页面翻译时,把翻译结果添加到生词本。

生词本分为文件生词本和网络生词本。文件生词本可以把生词和翻译添加到指定文件,网络生词本可以把生词和翻译上传到网络服务器,与 Anki 的记忆软件联动。

模板用来格式化生词本的输出,${from}表示原始语言,${to}表示目标语言,${fromT}表示翻译前的文字,${toT}表示翻译后的文字,${engine}表示使用的翻译引擎。

模板示例:

text
${fromT} -> ${toT} (${engine})

以Hello World为例,翻译结果为你好,世界,模板输出为:

text
Hello World -> 你好,世界 (ChatGPT)

注意在一些格式中,如 JSON,请不要忘了双引号。

文件生词本

文件生词本只需要指定路径path和模板template。由于文件生词本使用文本追加模式,所以不支持 JSON 格式,可以使用 JSONL、csv、txt 等格式。

csv 格式示例:

csv
"${fromT}", "${from}", "${toT}", "${to}", "${engine}"

文件示例内容如下,可以使用 Excel 等表格软件打开:

csv
...
"Hello World", "en", "你好,世界", "zh", "ChatGPT"
...

网络生词本

Url 和请求体(body)可以使用模板。

以 Anki 为例:

安装 AnkiConnect 插件,并在 Anki 中启用插件。

URL:http://127.0.0.1:8765

请求体(body)

json
{
  "action": "addNote",
  "version": 6,
  "params": {
    "note": {
      "deckName": "你的牌组",
      "modelName": "类型名称",
      "fields": {
        "Front": "${fromT}",
        "Back": "${toT}"
      },
      "options": {
        "allowDuplicate": false
      }
    }
  }
}

使用 LLM 模型翻译

支持本地LLM或者在线LLM。

先添加在线AI,见文档。然后添加翻译器,类型选择“大模型”

其他免费翻译服务

谷歌翻译、Yandex 翻译、腾讯交互式翻译,直接在软件设置中添加翻译器,测试通过即可。

DeeplX


--- METRICS ---