核心思路:纯前端、本地AI模型推理,图片不上传服务器。
体验地址 WoDeTool 。
一、方案概览
核心思路:纯前端、本地推理,图片不上传服务器,保护用户隐私。
通过用画笔标记水印区域(mark),浏览器在本地加载 LaMa inpainting 模型,通过 ONNX Runtime Web 完成修复,最后输出结果。
| 维度 | 选型 |
|---|---|
| 修复算法 | LaMa(Large Mask Inpainting,大区域图像修复) |
| 模型格式 | ONNX(lama_fp32.onnx,约 208MB) |
| 推理引擎 | ONNX Runtime Web 1.21.0 |
| 执行后端 | WASM(SIMD + 多线程),不用 WebGPU |
| 计算线程 | Web Worker(主线程只做 UI 和 Canvas) |
| 隐私 | 图片、掩码、推理全在浏览器内完成 |
二、整体架构
用户浏览器
├── 主线程
│ ├── 选图 / 画笔涂抹 → Canvas(原图 + 掩码)
│ ├── ROI 裁剪、缩放、张量转换
│ └── 结果贴回、展示、下载
│
├── Web Worker(inpaint.worker.ts)
│ └── ONNX Runtime → LaMa 推理(512×512)
│
├── IndexedDB
│ ├── LaMa 模型缓存(~208MB,版本化 key)
│ └── ORT WASM 二进制缓存
│
└── 静态资源
├── /models/lama_fp32.onnx → CDN
└── /ort-wasm/* → jsDelivr(onnxruntime-web)
三、为什么用 LaMa,而不是 OpenCV?
早期曾尝试 OpenCV.js + Canvas(cv.inpaint,TELEA / Navier-Stokes):
虽然他的js包很小,但用作去水印效果很差,特别是复杂的人像风景图等,基本无法接受。如果单纯去一些背景色单调,简单类的也能接受。所以基于大部分场景,还是舍弃这个方案。
四、加载与体验优化
因lama_fp32.onnx模型非常大(218M),在性能加载上会产生很多问题。所以尝试了下面的优化方案:
利用
indexDB来做缓存,避免每次重复加载
1. 全站空闲预加载
根布局挂载 InpaintModelPrefetch:
requestIdleCallback在浏览器空闲时下载模型、预热 Worker- 不阻塞首屏渲染
- 省流模式(
saveData)或 2G 网络自动跳过
2. 去水印页内预加载
进入工具页再次调用 preloadInpaintModel(),显示加载状态;模型就绪后「开始修复」可立即推理。
3. 三级缓存
| 层级 | 内容 |
|---|---|
| 内存 | cachedModel ArrayBuffer、已初始化的 Worker Session |
| IndexedDB | ONNX 模型、ORT WASM(带版本号,模型更新可失效旧缓存) |
| HTTP | CDN + 浏览器 HTTP 缓存 |
五、优势
- 隐私友好:图片不出浏览器
- 零服务端 GPU:CDN + 用户算力
- 效果优于传统 OpenCV inpaint
- ROI 策略让大图可用
- 预加载 + 缓存改善二次使用体验
借用ONNX 和LaMa 图片模型在本地浏览器端部署就可实现很好的去水印效果了~


