介绍说明
用js给图片添加水印并渲染到页面上,这里通过canvas来绘制,唯一注意的是图片不要有防盗链,不然会渲染失败,下面我们先看看步骤,最后附HTML前端实例!
步骤说明
一、将获取到图片路径,将图片转换为canvas
/**
* 图片路径转成canvas
* @param {图片url} url
*/
async function imgToCanvas(url) {
// 创建img元素
const img = document.createElement("img");
img.src = url;
img.setAttribute("crossOrigin", "anonymous"); // 防止跨域引起的 Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
await new Promise((resolve) => (img.onload = resolve));
// 创建canvas DOM元素,并设置其宽高和图片一样
const canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
// 坐标(0,0) 表示从此处开始绘制,相当于偏移。
canvas.getContext("2d").drawImage(img, 0, 0);
return canvas;
}
二、既然已经是canvas了,那就可以使用canvas的绘制文字的方法
//画布添加水印
const drawWaterMark = (canvas, textArray) => {
const ctx = canvas.getContext("2d");
let wmConfig = {
font: 'microsoft yahei',
textArray: textArray,
density: 2.5
}
let fontSize = 20;
let imgWidth = canvas.width;
let imgHeight = canvas.height;
ctx.fillStyle = "white";
ctx.font = `${fontSize}px ${wmConfig.font}`;
ctx.lineWidth = 1;
ctx.fillStyle = "rgba(255,255,255,1)";
ctx.textAlign = "left";
ctx.textBaseline = "middle";
// //文字坐标
const maxPx = Math.max(imgWidth, imgHeight);
const stepPx = Math.floor(maxPx / wmConfig.density);
let arrayX = [0];//初始水印位置 canvas坐标 0 0 点
while (arrayX[arrayX.length - 1] < maxPx / 2) {
arrayX.push(arrayX[arrayX.length - 1] + stepPx);
}
arrayX.push(...arrayX.slice(1, arrayX.length).map((el) => {
return -el;
}));
for (let i = 0; i < arrayX.length; i++) {
for (let j = 0; j < arrayX.length; j++) {
ctx.save();
ctx.translate(imgWidth / 2, imgHeight / 2); ///画布旋转原点 移到 图片中心
ctx.rotate(-Math.PI / 5);
if (wmConfig.textArray.length > 3) { //最多显示三行水印,也可以根据需要自定义
wmConfig.textArray = wmConfig.textArray.slice(0, 3);
}
wmConfig.textArray.forEach((el, index) => {
let offsetY = fontSize * index + 2;
ctx.fillText(el, arrayX[i], arrayX[j] + offsetY);
});
ctx.restore();
}
}
};
/**
* canvas添加水印
* @param {canvas对象} canvas
* @param {水印文字} text
*/
function addWatermark(canvas, text) {
const ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.textBaseline = "middle";
ctx.textAlign = 'center';
ctx.font = '28px Arial';
//设置文字水印居中的:canvas.width/2
//不需要居中请改为自定义值
ctx.fillText(text,canvas.width/2, 50);
return canvas;
}
三、水印绘制完成后,再将canvas转换为图片格式
/**
* canvas转成img
* @param {canvas对象} canvas
*/
function convasToImg(canvas) {
// 新建Image对象,可以理解为DOM
var image = new Image();
// canvas.toDataURL 返回的是一串Base64编码的URL
// 指定格式 PNG
image.src = canvas.toDataURL("image/png");
return image;
}
四、最后运行一下实例
// 运行示例
async function run() {
const imgUrl = "https://desk-fd.zol-img.com.cn/t_s960x600c5/g2/M00/0A/01/ChMlWlx48_-IPaIeACiSSJ8Spe4AAIiVgPF3ykAKJJg340.jpg";
// 1.图片路径转成canvas
const tempCanvas = await imgToCanvas(imgUrl);
// 2.canvas添加水印
drawWaterMark(tempCanvas, ['自定义水印','水印2'])
// 3.canvas转成img
const img = convasToImg(tempCanvas);
// 查看效果
document.body.appendChild(img);
}
注意:图片地址不要有防盗链,否则不会输出画布!
五、效果展示
完整代码
实例演示1:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>添加文字水印</title>
</head>
<body>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
/**
* 图片路径转成canvas
* @param {图片url} url
*/
async function imgToCanvas(url) {
// 创建img元素
const img = document.createElement("img");
img.setAttribute("crossOrigin", "anonymous");
img.src = url;
// 防止跨域引起的 Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
await new Promise((resolve) => (img.onload = resolve));
// 创建canvas DOM元素,并设置其宽高和图片一样
const canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
// 坐标(0,0) 表示从此处开始绘制,相当于偏移。
canvas.getContext("2d").drawImage(img, 0, 0);
return canvas;
}
//画布添加水印
const drawWaterMark = (canvas, textArray) => {
const ctx = canvas.getContext("2d");
let wmConfig = {
font: 'microsoft yahei',
textArray: textArray,
density: 2.5
}
let fontSize = 20;
let imgWidth = canvas.width;
let imgHeight = canvas.height;
ctx.fillStyle = "white";
ctx.font = `${fontSize}px ${wmConfig.font}`;
ctx.lineWidth = 1;
ctx.fillStyle = "rgba(255,255,255,1)";
ctx.textAlign = "left";
ctx.textBaseline = "middle";
// //文字坐标
const maxPx = Math.max(imgWidth, imgHeight);
const stepPx = Math.floor(maxPx / wmConfig.density);
let arrayX = [0];//初始水印位置 canvas坐标 0 0 点
while (arrayX[arrayX.length - 1] < maxPx / 2) {
arrayX.push(arrayX[arrayX.length - 1] + stepPx);
}
arrayX.push(...arrayX.slice(1, arrayX.length).map((el) => {
return -el;
}));
for (let i = 0; i < arrayX.length; i++) {
for (let j = 0; j < arrayX.length; j++) {
ctx.save();
ctx.translate(imgWidth / 2, imgHeight / 2); ///画布旋转原点 移到 图片中心
ctx.rotate(-Math.PI / 5);
if (wmConfig.textArray.length > 3) { //最多显示三行水印,也可以根据需要自定义
wmConfig.textArray = wmConfig.textArray.slice(0, 3);
}
wmConfig.textArray.forEach((el, index) => {
let offsetY = fontSize * index + 2;
ctx.fillText(el, arrayX[i], arrayX[j] + offsetY);
});
ctx.restore();
}
}
};
/**
* canvas转成img
* @param {canvas对象} canvas
*/
function convasToImg(canvas) {
// 新建Image对象,可以理解为DOM
var image = new Image();
// canvas.toDataURL 返回的是一串Base64编码的URL
// 指定格式 PNG
image.src = canvas.toDataURL("image/png");
return image;
}
// 运行示例
async function run() {
const imgUrl = "https://desk-fd.zol-img.com.cn/t_s960x600c5/g2/M00/0A/01/ChMlWlx48_-IPaIeACiSSJ8Spe4AAIiVgPF3ykAKJJg340.jpg";
// 1.图片路径转成canvas
const tempCanvas = await imgToCanvas(imgUrl);
// 2.canvas添加水印
drawWaterMark(tempCanvas, ['自定义水印','水印2'])
// 3.canvas转成img
const img = convasToImg(tempCanvas);
// 查看效果
document.body.appendChild(img);
}
run();
</script>
</html>
实例演示2:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>添加文字水印</title>
</head>
<body>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
/**
* 图片路径转成canvas
* @param {图片url} url
*/
async function imgToCanvas(url) {
// 创建img元素
const img = document.createElement("img");
img.setAttribute("crossOrigin", "anonymous");
img.src = url;
// 防止跨域引起的 Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
await new Promise((resolve) => (img.onload = resolve));
// 创建canvas DOM元素,并设置其宽高和图片一样
const canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
// 坐标(0,0) 表示从此处开始绘制,相当于偏移。
canvas.getContext("2d").drawImage(img, 0, 0);
return canvas;
}
/**
* canvas添加水印
* @param {canvas对象} canvas
* @param {水印文字} text
*/
function addWatermark(canvas, text) {
const ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.textBaseline = "middle";
ctx.textAlign = 'center';
ctx.font = '28px Arial';
//设置文字水印居中的:canvas.width/2
//不需要居中请改为自定义值
ctx.fillText(text,canvas.width/2, 50);
return canvas;
}
/**
* canvas转成img
* @param {canvas对象} canvas
*/
function convasToImg(canvas) {
// 新建Image对象,可以理解为DOM
var image = new Image();
// canvas.toDataURL 返回的是一串Base64编码的URL
// 指定格式 PNG
image.src = canvas.toDataURL("image/png");
return image;
}
// 运行示例
async function run() {
const imgUrl ="https://desk-fd.zol-img.com.cn/t_s960x600c5/g2/M00/0A/01/ChMlWlx48_-IPaIeACiSSJ8Spe4AAIiVgPF3ykAKJJg340.jpg";
// 1.图片路径转成canvas
const tempCanvas = await imgToCanvas(imgUrl);
// 2.canvas添加水印
const canvas = addWatermark(tempCanvas, "www.360mb.net");
// 3.canvas转成img
const img = convasToImg(canvas);
// 查看效果
document.body.appendChild(img);
}
run();
</script>
</html>
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END