- 作者

- Name
- Jim
- Role
- AI协作 & 全栈创造者
敏感信息处理的痛点
在办理入职审核、房屋租赁、银行借贷或出海资质证明时,我们经常需要提交身份证、营业执照或护照复印件。在这些证件上加盖“仅供某某业务办理使用,他用无效”的防伪水印是基础的安全常识。
然而市面上大多数免费水印网站,都会把图片悄悄上传至其云端服务器进行合成,不仅造成敏感个人身份信息(PII)泄露,遇到大批量图片时处理速度也极慢。
纯前端批量水印工具 (Batch Watermark Tool) 专注于一件事情:数据绝对不离开用户设备,100% 浏览器本地瞬时完成批量水印加注。
核心技术实现
1. HTML5 Canvas 高清离屏渲染与抗拉伸
很多水印工具在图片缩放后,文字会出现模糊和锯齿。我们采用了动态 DPI 与物理像素比(Device Pixel Ratio)适配机制:
// 针对高分辨率原图的坐标系动态缩放矩阵
function renderWatermarkToCanvas(image, watermarkText, options) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
// 保持全尺寸底图渲染,不损失原图细节
ctx.drawImage(image, 0, 0);
// 倾斜 30 度平铺全屏水印矩阵,防止边缘被轻易裁切
ctx.rotate((-30 * Math.PI) / 180);
ctx.font = `${options.fontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto`;
ctx.fillStyle = `rgba(180, 180, 180, ${options.opacity})`;
// 循环平铺密集绘制
...
}
2. Web Worker 异步批处理与主线程解耦
当用户一次性拖入 100+ 张单反拍摄的 10MB 大图时,如果在主线程直接循环处理 Canvas,浏览器标签页会瞬间陷入“无响应(Unresponsive)”假死状态。
我们利用 OffscreenCanvas 与 Web Worker:
- 主线程将原始
File / Blob对象传递给 Worker 池; - Worker 线程利用后台 OffscreenCanvas 并行渲染,避免阻塞 UI 交互;
- 主线程保留流畅的实时进度条与取消操作,处理完毕后通过 JSZip 在前端直接将所有图片打包为
.zip供一键下载。
极简 Docker 私有化交付(仅 15MB)
为了方便企业内部内网部署,项目编写了高优化的多阶段构建 Dockerfile:
# 仅需超轻量的 Alpine Nginx 即可承载
FROM nginx:alpine-slim
COPY ./public /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
最终镜像压缩包仅约 15 MB,支持内网离线机房一键分发运行:
# 启动本地 Docker 容器
docker run -d -p 8080:80 --name watermark-tool jim-purch/batch-watermark:latest
访问 http://localhost:8080 即可在局域网内任意终端离线安全使用。
项目源码与部署配置见:GitHub Jim-purch/batch-watermark-tool。
在 GitHub 查看源码 →感谢阅读与实践