如何实现前端添加水印

718 阅读8分钟

一、使用CSS添加水印

使用CSS给需要添加水印的元素添加背景图即可

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS添加水印</title>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #f0f0f0;
    }

    .watermark {
      position: absolute;
      top: -300px;
      right: 0;
      left: 0;
      bottom: 0;
      width: 100%;
      height: 100%;
      z-index: 999;
      background-image: url("./watermark.png");
      background-repeat: no-repeat;
      background-position: center;
      opacity: 0.8;
      pointer-events: none;  /* 设置水印不可点击,确保水印不影响用户操作 */
    }

    .container { 
      position: relative;
      background-color: aquamarine;
      height: 400px;
    }
  </style>
</head>

<body>
  <div class="container">
    <h1>CSS添加水印</h1>
    <p>水印是一种视觉效果,用于保护版权、标识来源或防止未经授权的复制。</p>
    <p>在网页设计中,我们可以使用CSS来添加水印效果。</p>
    <p>下面是一个简单的示例,展示如何使用CSS来添加水印。</p>
  </div>
  <div class="watermark"></div>
</body>

</html>

wm1.jpg

优点:

  • 简单易用,兼容性好
  • 仅使用CSS,性能好

缺点:

  • 灵活性差,仅适用于静态页面,对于复杂布局或动态内容表现不好
  • 防篡改能力差,可以通过修改CSS轻松去除

二、使用Canvas添加水印

通过 Canvas 元素动态绘制水印,适用于图像或者页面上的任何元素。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Canvas添加水印</title>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #f0f0f0;
    }

    .watermark {
      position: absolute;
      top: -300px;
      right: 0;
      left: 0;
      bottom: 0;
      width: 100%;
      height: 100%;
      z-index: 999;
      background-repeat: no-repeat;
      background-position: center;
      opacity: 0.8;
      pointer-events: none;  /* 设置水印不可点击,确保水印不影响用户操作 */
    }

    .container { 
      position: relative;
      background-color: aquamarine;
      width: 1800px;
      height: 2000px;
    }
  </style>
</head>

<body>
  <div class="container">
    <h1>Canvas添加水印</h1>
    <p>水印是一种视觉效果,用于保护版权、标识来源或防止未经授权的复制。</p>
    <p>在网页设计中,我们可以使用Canvas来添加水印效果。</p>
    <p>下面是一个简单的示例,展示如何使用Canvas来添加水印。</p>
  </div>
  <canvas id="watermarkCanvas" class="watermark"></canvas>
</body>
<script>

  // 添加文本水印
  window.onload = function () { 
    const canvas = document.getElementById("watermarkCanvas");
    const ctx = canvas.getContext("2d");

    // 获取container的宽高
    const container = document.querySelector('.container');
    const containerWidth = container.offsetWidth;
    const containerHeight = container.offsetHeight;
    // 设置canvas的宽高
    canvas.width = containerWidth;
    canvas.height = containerHeight;

    // 设置水印文本
    const watermarkText = "测试canvas水印©2025";
    // 设置水印字体和大小
    ctx.font = "30px Arial";
    ctx.fillStyle = "rgba(0, 0, 0, 0.5)"; // 设置水印颜色和透明度
    ctx.textAlign = "center";
    ctx.textBaseline = "middle"; // 设置水印位置

    // 向右400px,重复添加水印
    const x = 400;
    const y = containerHeight / 2;
    const interval = 200; // 水印之间的间隔
    let i = 0;
    // 循环添加水印
    function addWatermark() {
      ctx.save();
      ctx.translate(x + i * interval, y);
      ctx.rotate(-Math.PI / 180 * 45); // 旋转45度
      ctx.fillText(watermarkText, 0, 0);
      ctx.restore();
    }

    for (i = 0; i < 5; i++) {
      addWatermark();
    }

     // 添加图片水印
    const img = new Image();
    img.src = './watermark.png'; // 替换为你的水印图片地址
    img.onload = function () {
      const imgIntervalX = 300; // 横向间隔
      const imgIntervalY = 500; // 纵向间隔
      const imgXStart = 400;    // 起始X坐标
      const imgYStart = 300;    // 起始Y坐标

      for (let row = 0; row < 4; row++) {
        for (let col = 0; col < 4; col++) {
          const posX = imgXStart + col * imgIntervalX; // 计算图片的X坐标
          const posY = imgYStart + row * imgIntervalY; // 计算图片的Y坐标

          ctx.save();
          ctx.globalAlpha = 0.6; // 图片透明度
          ctx.drawImage(img, posX, posY, 100, 100); // 绘制图片并设置尺寸
          ctx.restore();
        }
      }
    };
  }
</script>
</html>

wm2.jpg

优点:

  • 动态生成水印,可根据需要选择水印类型
  • 支持复杂的水印样式
  • 水印嵌入到Canvas中,不易被去除

缺点:

  • 需要Javascript支持,相比CSS加水印复杂一些
  • 有一定的性能开销,在性能差的设备上体验可能会有影响

三、使用Svg添加水印

使用 SVG 元素来实现水印,可以在矢量图形上显示水印

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Svg添加水印</title>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #f0f0f0;
    }

    .watermark {
      position: absolute;
      top: -300px;
      right: 0;
      left: 0;
      bottom: 0;
      width: 100%;
      height: 100%;
      z-index: 999;
      background-repeat: no-repeat;
      background-position: center;
      opacity: 0.8;
      pointer-events: none;  /* 设置水印不可点击,确保水印不影响用户操作 */
    }

    .container { 
      position: relative;
      background-color: aquamarine;
      width: 1500px;
      height: 400px;
    }
  </style>
</head>

<body>
  <div class="container">
    <h1>Svg添加水印</h1>
    <p>水印是一种视觉效果,用于保护版权、标识来源或防止未经授权的复制。</p>
    <p>在网页设计中,我们可以使用Svg来添加水印效果。</p>
    <p>下面是一个简单的示例,展示如何使用Svg来添加水印。</p>
  </div>
  <div class="watermark">
    <svg width="100%" height="100%">
      <text x="50%" y="50%" fill="#000000" font-size="40" transform="rotate(30, 1200, -300)" font-family="Arial" text-anchor="middle">Svg水印</text>
    </svg>
  </div>
</body>
</html>

image.png

优点:

  • 水印缩放自适应,适合响应式布局
  • 使用矢量图形,水印不会失真

缺点:

  • 性能不如 canvas 好
  • 水印可以通过 DOM 操作移除
  • 对老版本浏览器兼容性较差(例如IE)

四、使用Vue自定义指令添加水印

使用 Vue 自定义指令,可以根据需要动态在任意元素上添加图片或文字水印

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue自定义指令添加水印</title>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #f0f0f0;
    }

    .watermark-container {
      position: relative;
      width: 1500px;
      height: 400px;
      overflow: hidden;
    }

    .container {
      position: relative;
      background-color: aquamarine;
      width: 100%;
      height: 100%;
    }

    .watermark-container span,
    .watermark-container img {
      user-select: none;
    }
  </style>
</head>

<body>
  <div id="app">
    <div class="watermark-container"
         v-watermark="{ text: 'Vue自定义指令水印', imgSrc: './watermark.png' }">
      <div class="container">
        <h1>Vue自定义指令添加水印</h1>
        <p>水印是一种视觉效果,用于保护版权、标识来源或防止未经授权的复制。</p>
        <p>下面是一个简单的示例,展示如何使用Vue自定义指令来添加水印。</p>
      </div>
    </div>
  </div>

  <!-- 引入 Vue -->
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    // 自定义指令:v-watermark
    Vue.directive('watermark', {
      bind(el, binding) {
        const { text, imgSrc } = binding.value;

        // 创建水印容器
        const watermarkDiv = document.createElement('div');
        watermarkDiv.style.position = 'absolute';
        watermarkDiv.style.top = '0';
        watermarkDiv.style.left = '0';
        watermarkDiv.style.width = '100%';
        watermarkDiv.style.height = '100%';
        watermarkDiv.style.pointerEvents = 'none';
        watermarkDiv.style.zIndex = '9999';
        watermarkDiv.style.display = 'flex';
        watermarkDiv.style.alignItems = 'center';
        watermarkDiv.style.justifyContent = 'center';
        watermarkDiv.style.flexDirection = 'column';

        if (text) {
          // 添加文字水印
          const textWatermark = document.createElement('span');
          textWatermark.innerText = text;
          textWatermark.style.color = 'rgba(0, 0, 255, 0.8)';
          textWatermark.style.fontSize = '24px';
          watermarkDiv.appendChild(textWatermark);
        }

        if (imgSrc) {
          // 添加图片水印
          const imgWatermark = document.createElement('img');
          imgWatermark.src = imgSrc;
          imgWatermark.style.opacity = '0.8';
          imgWatermark.style.maxWidth = '200px';
          watermarkDiv.appendChild(imgWatermark);
        }

        el.style.position = 'relative';
        el.appendChild(watermarkDiv);

        // 缓存元素便于 unbind 使用
        el._watermarkDiv = watermarkDiv;
      },
      unbind(el) {
        if (el._watermarkDiv && el.contains(el._watermarkDiv)) {
          el.removeChild(el._watermarkDiv);
          delete el._watermarkDiv;
        }
      }
    });

    // 初始化 Vue 实例
    new Vue({
      el: '#app'
    });
  </script>
</body>

</html>

wm4.jpg

优点:

  • 通过指令动态添加水印,灵活性高,可以在任何元素中使用
  • 支持同时添加图片和文字水印,适合需要动态配置水印内容的场景

缺点:

  • 对非 Vue 项目不适用
  • 需要手动处理兼容性问题:如不同浏览器对 transform、pointer-events 的支持差异,需要手动处理

五、使用第三方库添加水印

使用 JavaScript 图像处理库添加水印,如 Fabric.js

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>fabric.js 添加水印</title>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #f0f0f0;
      margin: 0;
      padding: 0;
    }

    .container {
      position: relative;
      background-color: aquamarine;
      width: 1500px;
      height: 400px;
      display: flex;
      align-items: center;
      justify-content: center;
      flex-direction: column;
    }

    canvas {
      border: 1px solid #ccc;
      display: block;
      z-index: 999;
    }
  </style>
</head>

<body>
  <div class="container">
    <h1>fabric.js添加水印</h1>
    <p>水印是一种视觉效果,用于保护版权、标识来源或防止未经授权的复制。</p>
    <p>下面是一个简单的示例,展示如何使用fabric.js来添加水印。</p>
    <canvas id="canvas"></canvas>
  </div>

  <!-- 引入 fabric.js 最新版本 -->
  <script src="https://cdn.jsdelivr.net/npm/fabric@latest/dist/index.min.js"></script>

  <script>
    // 等待 DOM 加载完成后再初始化
    window.addEventListener('DOMContentLoaded', () => {
      if (typeof fabric === 'undefined') {
        console.error('fabric.js 未正确加载');
        return;
      }

      const canvas = new fabric.Canvas('canvas');

      // 创建水印文字
      const watermark = new fabric.Textbox('Watermark © 2025', {
        left: canvas.getWidth() / 2,
        top: canvas.getHeight() / 2,
        fontSize: 24,
        fill: 'rgba(255, 0, 0, 0.7)',
        angle: -30
      });

      // 添加水印到画布
      canvas.add(watermark);
    });
  </script>
</body>

</html>

wrm5.jpg

优点:

  • 功能强大:提供了丰富的 API,可以轻松实现复杂的图形操作
  • 易于使用:官方提供了详细的文档和示例,方便学习和参考

缺点:

  • 引入第三方库,增加页面负载
  • 安全性考虑:使用第三方库时,需要对其安全性进行评估,避免潜在的安全风险

六、总结

实现方法核心技术原理优点缺点适用场景
CSS 水印通过background-image或绝对定位元素叠加背景图- 实现简单,无需 JS
- 兼容性好,性能开销极低
- 仅支持静态图片水印
- 可通过浏览器工具轻松移除
- 无法应对动态内容
静态展示页面、简单版权标识
Canvas 水印使用 Canvas API 动态绘制文字 / 图片水印- 支持动态生成复杂样式(旋转、重复排列)
- 水印与内容融合度高,不易被直接移除
- 需要 JavaScript 支持
- 大规模渲染时可能影响性能
- 复杂场景下代码逻辑较繁琐
图片预览页、动态内容区域、需要防截图保护的场景
SVG 水印通过矢量图形语法定义水印内容- 矢量格式,缩放不失真
- 适合响应式布局,自适应不同屏幕
- 性能略低于 Canvas
- 可通过 DOM 操作移除
- 旧版浏览器兼容性较差(如 IE)
需高清缩放的场景、图标类水印
Vue 自定义指令基于 Vue 框架的指令系统动态注入水印元素- 组件化集成,可复用性高
- 支持通过指令参数灵活配置水印内容
- 仅限 Vue 项目使用
- 需处理浏览器兼容性差异
Vue 框架开发的管理后台、需要动态配置水印的组件
第三方库(如 Fabric.js)基于专业图形库提供的 API 生成水印- 功能强大,支持文字、图片、复杂图形组合
- 提供丰富的自定义选项(透明度、旋转、阴影等)
- 引入库文件增加页面加载成本
- 需学习第三方 API,上手成本较高
专业图片编辑工具、需要高度定制化水印的场景