文章目录[隐藏]

介绍说明

用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);
    }

注意:图片地址不要有防盗链,否则不会输出画布!

五、效果展示

用 JS 给图片添加水印并渲染插图

完整代码

实例演示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>

 

发表回复

后才能评论