canvas批量加水印核心是“预加载→逐帧绘制→合成导出”:1.用promise.all预加载所有图像资源;2.标准化水印位置、缩放与透明度配置;3.复用主canvas并用离屏canvas缓存水印;4.统一导出为dataurl或blob并聚合结果。

Canvas 批量加水印的核心是“预加载→逐帧绘制→合成导出”,关键在避免阻塞、统一坐标逻辑、控制渲染顺序。
1. 图像资源预加载与状态管理
批量处理前必须确保所有原图和水印图已加载完成,否则 drawImage 会静默失败。推荐用 Promise.all 统一管控:
- 为每张原图和水印图创建
Image实例,绑定onload和onerror - 将每个加载任务包装为 Promise,成功时 resolve 图像对象,失败时 reject 错误信息
- 使用
Promise.all(imagePromises)确保全部就绪后再进入绘制阶段
2. 水印配置标准化(位置/缩放/透明度)
避免每张图重复计算,提前定义可复用的水印参数对象:
- 位置模式:支持 'center'、'bottom-right'、'tiled'(平铺)、'custom(x,y)' 四种,统一转换为 canvas 坐标
-
尺寸适配:水印宽度设为原图宽的 15%~25%,保持宽高比;文字水印用
ctx.measureText动态算宽高 -
混合效果:设置
ctx.globalAlpha = 0.3,叠加前保存状态,绘制后恢复,防止影响后续操作
3. Canvas 复用与离屏渲染优化
不为每张图新建 canvas 元素,而是复用一个主 canvas,并用离屏 canvas(document.createElement('canvas'))预处理水印:
- 创建一个固定尺寸的离屏 canvas,一次性绘制并缓存水印图案(含旋转、透明度)
- 主 canvas 每次重置尺寸为当前原图宽高,清空(
ctx.clearRect(0,0,w,h))后先 drawImage 原图 - 再根据配置位置,多次调用
ctx.drawImage(offlineCanvas, x, y)贴入水印(平铺时循环计算坐标)
4. 批量导出与结果聚合
绘制完成后,用 toDataURL 或 toBlob 获取结果,注意 MIME 类型与质量控制:
- 导出为
image/jpeg可传第二个参数(0.8~0.95)控制压缩质量,减少体积 - 用
Blob方式更利于大图或后续上传,配合URL.createObjectURL(blob)生成可下载链接 - 结果以数组形式返回,每项包含原图索引、dataUrl/blob、文件名建议(如
original_name_watermarked.jpg)
整个流程不依赖第三方库,纯原生 Canvas API 即可实现稳定批量水印,重点在于资源调度有序、绘制逻辑解耦、内存及时释放。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










