纯前端实现去图片水印方案总结

发布于2026年7月02日 23:10:55

核心思路:纯前端、本地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 + Canvascv.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 图片模型在本地浏览器端部署就可实现很好的去水印效果了~

体验地址:
https://wodetool.com/tools/image-watermark-remover