在html5中实现图片水印添加,核心依赖canvas绘图能力,通过加载原始图片、绘制水印内容、导出最终图片三个核心步骤即可完成,整个过程不需要依赖第三方库,原生api就能实现。

实现原理说明
canvas是html5提供的绘图容器,支持加载外部图片资源并绘制到画布上,同时可以在画布上绘制文字、图形等内容。给图片加水印的本质就是先把原始图片绘制到canvas上,再把水印内容绘制到图片上方,最后把canvas的内容导出为新的图片即可。
完整实现步骤
1. 初始化canvas元素
首先在页面中创建canvas元素,设置合适的宽高,后续所有绘制操作都在这个画布上完成。
<canvas id="watermarkCanvas" style="display:none;"></canvas> <img id="resultImg" alt="带水印的图片"> <input type="file" id="imgInput" accept="image/*">
2. 加载原始图片
通过文件上传或者指定图片地址获取原始图片,等待图片加载完成后再进行后续绘制操作,避免图片未加载完成导致绘制异常。
function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = src;
});
}
3. 绘制图片和水印
先设置canvas的宽高和原始图片一致,然后把原始图片绘制到canvas上,接着设置水印的样式,把水印内容绘制到图片的指定位置。
async function addWatermark(imgSrc, watermarkText) {
// 加载原始图片
const originImg = await loadImage(imgSrc);
// 获取canvas元素和上下文
const canvas = document.getElementById('watermarkCanvas');
const ctx = canvas.getContext('2d');
// 设置canvas宽高为图片宽高
canvas.width = originImg.width;
canvas.height = originImg.height;
// 绘制原始图片
ctx.drawImage(originImg, 0, 0, originImg.width, originImg.height);
// 设置水印样式
ctx.font = '30px Microsoft YaHei';
ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
ctx.textAlign = 'right';
ctx.textBaseline = 'bottom';
// 绘制水印文字,放在右下角位置
ctx.fillText(watermarkText, canvas.width - 20, canvas.height - 20);
// 导出带水印的图片
return canvas.toDataURL('image/png');
}
4. 绑定触发事件
通过文件上传获取用户选择的图片,调用上面的水印添加方法,把最终生成的带水印图片显示在页面上。
document.getElementById('imgInput').addEventListener('change', async (e) => {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = async (event) => {
const imgSrc = event.target.result;
const resultImgUrl = await addWatermark(imgSrc, '示例水印');
document.getElementById('resultImg').src = resultImgUrl;
};
reader.readAsDataURL(file);
});
注意事项
- 如果原始图片是跨域资源,需要设置<img>标签的crossOrigin属性为anonymous,否则canvas转出的图片会报错
- 水印的样式可以根据需求调整,比如修改字体大小、颜色、透明度、位置,也可以绘制图片形式的水印
- canvas.toDataURL导出的图片是base64格式,如果需要转成文件形式上传,可以把base64转成Blob对象再处理
扩展:图片水印实现
如果需要添加图片形式的水印,只需要把绘制文字的步骤替换成绘制图片即可,示例代码如下:
async function addImageWatermark(imgSrc, watermarkImgSrc) {
const originImg = await loadImage(imgSrc);
const watermarkImg = await loadImage(watermarkImgSrc);
const canvas = document.getElementById('watermarkCanvas');
const ctx = canvas.getContext('2d');
canvas.width = originImg.width;
canvas.height = originImg.height;
ctx.drawImage(originImg, 0, 0);
// 绘制图片水印,设置水印宽高为100*100,放在左上角
ctx.drawImage(watermarkImg, 20, 20, 100, 100);
return canvas.toDataURL('image/png');
}