H5图片加水印上传的核心流程是:File→Image→canvas绘制(文字/图片水印)→toBlob导出→FormData上传;全程前端完成,需注意兼容性、大图压缩、时间水印及服务端校验。

在 H5 中给图片加水印再上传,核心是:先用 File 对象读取原始图片 → 转为 Image → 绘制到 canvas 上并叠加文字或图片水印 → 导出带水印的 blob 或 base64 → 构造 FormData 发送给服务器。整个过程完全在前端完成,不依赖后端图像处理。
获取图片并转成可绘制的 Image 对象
用户通过 <input type="file" accept="image/*"> 选择图片后,需用 FileReader 将其转为 URL,再创建 Image 实例:
- 监听
input的change事件,取files[0] - 用
FileReader.readAsDataURL(file)读取为 base64 字符串 - 将该字符串赋给
img.src,并在img.onload中开始绘图
用 canvas 绘制带水印的图片
创建 canvas,按原图尺寸设置宽高,用 ctx.drawImage() 先画底图,再叠加水印:
- 文字水印建议使用
ctx.font(如"16px sans-serif")、ctx.fillStyle(支持rgba(0,0,0,0.2)半透明)和ctx.fillText() - 推荐水印位置:右下角(
canvas.width - 20, canvas.height - 10)或斜向铺满(需循环绘制并旋转ctx.rotate()) - 若要加 logo 图片水印,需等 logo 图片也加载完成后再统一绘制
导出水印图并上传到服务器
调用 canvas.toBlob(callback, 'image/jpeg', 0.9) 得到带水印的 Blob 文件,再封装进 FormData:
- 注意:
toBlob是异步的,回调中才能拿到 Blob - 用
formData.append('image', blob, 'watermarked.jpg')添加字段,文件名可选 - 用
fetch('/upload', { method: 'POST', body: formData })发送,无需设Content-Type(浏览器自动添加 boundary)
补充建议:兼顾兼容性与体验
实际项目中还需考虑这些细节:
- 安卓部分 WebView 不支持
capture="camera",可配合accept="image/*"+ 用户引导说明拍照入口 - 大图(如 4K 照片)直接绘制易卡顿,建议先用
canvas压缩到宽度 ≤ 1200px 再加水印 - 时间水印可用
new Date().toLocaleString('zh-CN')动态生成,含年月日时分秒更防伪 - 服务端接收时,仍需校验文件类型和大小,前端水印不能替代后端安全控制


















