README file from
GithubImage Editor
English: Annotate and crop images in place. Right-click any image in your vault to open the built-in editor — draw, add text or mosaic, crop — then save to replace the original instantly.
Features (English)
- Right-click any embedded image (reading mode / live preview) to open the built-in editor
- Annotation tools: pen, line, arrow, rectangle, ellipse, text, mosaic — with undo / redo and keyboard shortcuts
- Crop with rule-of-thirds guides; apply or cancel at any time
- Save to replace the original image, or export as a new PNG file
- Non-PNG images (JPG / WebP / BMP / GIF) are auto-converted to PNG and all vault links are updated automatically
在 Obsidian 文档里右键图片 → 编辑图片,直接打开内置图片编辑器做标注和裁剪,点「完成」后原图被替换、文档里的图片立即刷新。
功能
| 能力 | 说明 |
|---|---|
| 右键唤起 | 在阅读模式 / 实时预览里右键任意内嵌图片,菜单出现「编辑图片」 |
| 多开 | 每张图一个独立标签页,可同时开多个编辑器;同一张图重复右键会聚焦已开的那一个 |
| 标注 | 画笔、直线、箭头、矩形、椭圆、文本、马赛克(矩形 / 椭圆支持半透明填充) |
| 裁剪 | 拖出选区,8 个手柄微调,支持三分参考线,可撤销 |
| 视图 | 滚轮缩放(以光标为中心)、空格或抓手拖拽平移、适应窗口 / 1:1 |
| 历史 | 撤销 / 重做,最多 40 步;裁剪也进历史栈 |
| 保存 | 覆盖原图,或另存为新 PNG 不动原图 |
安装
把这三个文件放进 <你的库>/.obsidian/plugins/image-editor-xhz/:
main.js
manifest.json
styles.css
然后在 Obsidian「设置 → 第三方插件」里刷新并启用 Image Editor (标注 / 裁剪)。
也可以直接:
npm install
npm run build # 类型检查 + 压缩打包,产出 main.js
开发时用 npm run dev 进入 esbuild 监听模式。
使用
打开编辑器
- 在文档中的图片上右键 → 编辑图片
- 命令面板:
编辑光标处的图片(光标放在那一行即可) - 命令面板:
打开图片进行编辑…(模糊搜索全库图片) - 文件管理器里右键图片文件 → 编辑图片
快捷键
| 按键 | 作用 |
|---|---|
P L A R O T M C H |
画笔 / 直线 / 箭头 / 矩形 / 椭圆 / 文本 / 马赛克 / 裁剪 / 抓手 |
Ctrl/⌘ + Z |
撤销 |
Ctrl/⌘ + Shift + Z、Ctrl/⌘ + Y |
重做 |
Ctrl/⌘ + S |
保存并替换原图 |
Enter |
裁剪模式下应用裁剪 |
Esc |
取消文本输入 / 退出裁剪 |
| 滚轮 | 以光标为中心缩放 |
Shift + 滚轮 |
水平平移 |
| 空格 + 拖拽、中键拖拽 | 平移视图 |
文本工具:点一下图片,出现输入框,Ctrl + Enter 确认,Esc 取消。
保存行为
- 原图是 PNG:直接覆盖原文件,文档里的图片会立刻刷新。
- 原图是 JPG / WebP / BMP:PNG 是有损格式之外的新格式,插件会另存为同名
.png, 并自动把全库 md 里指向原图的链接改到新文件(wikilink 和![]()都支持, 含|300、#center参数以及带空格路径)。是否删除原图可在设置里选,默认不动。 - 另存为:生成
原名-edited.png,原图保持不变。 - 关闭标签页时如果有未保存的修改,会弹出提醒(标题栏也会带
*标记)。
设置
设置 → 第三方插件 → Image Editor:
- 默认工具 / 颜色 / 线宽 / 文本字号
- 保存后自动关闭编辑器
- 转换格式后是否把原图移入回收站
- 阅读模式右键菜单兜底(阅读模式下 Obsidian 不一定广播右键事件,开启后会往弹出的菜单里补一个「编辑图片」)
实现要点
- 分层绘制:
base(底图)+composite(底图叠所有形状)+ 屏幕 canvas。 所有形状存的是原始图像像素坐标,缩放、裁剪、导出都不失真。 马赛克需要读取已合成像素,所以必须在 composite 层做。 - 多开:单个 view type +
workspace.getLeaf('tab'),每个 leaf 一个ItemView实例, 内部按state.file区分图片;同一路径会被重定向到已开的标签页。 - 图片定位:DOM 路径(阅读模式
.internal-embed、实时预览<img>的app://src) 加上源码路径(editor.posAtMouse+ 行内 embed 正则)双保险。 - 即时刷新:用
vault.modifyBinary写入,Obsidian 会重新生成带 mtime 的图片地址, 文档里的渲染随之更新,不需要重启或手动刷新。
项目结构
src/
main.ts 插件入口:右键菜单、命令、设置
editor-view.ts 编辑器视图:工具栏、保存、链接迁移
canvas-engine.ts 绘制引擎:形状、裁剪、历史、导出
image-resolver.ts 从右键位置 / 光标解析出图片文件
image-loader.ts 二进制 → <img>
icons.ts 内联 SVG 图标(不依赖 lucide 版本)
utils.ts / types.ts
test/ 冒烟测试 + 逻辑测试(npm test)
npm test 会用 stub 顶替 obsidian,在 Node 里跑 29 项用例,覆盖链接替换正则、
路径清洗、几何计算以及引擎的绘制 / 撤销 / 裁剪 / 导出流程。