大数跨境

原生Canvas实现图片自动居中水印

原生Canvas实现图片自动居中水印 wordpress知识
2026-09-17
8

极简原生 Canvas 图片水印方案

在内容创作与自媒体运营中,图片水印是基础的版权防护手段。本文介绍一套基于原生 JavaScript 与 Canvas 的极简水印方案:上传图片即可自动居中生成自适应水印。该方案代码精简、无第三方依赖,支持纯前端本地处理,可直接嵌入项目使用。

核心特性

  • 零依赖架构:纯原生 JS+Canvas 实现,无需任何框架或插件。
  • 智能自适应:水印文字大小根据图片尺寸动态调整,大图大字、小图小字。
  • 美观防盗:采用半透明白色水印固定居中展示,静态无旋转,兼顾视觉效果与版权保护。
  • 隐私安全:全程前端本地处理,图片不上传服务器,彻底规避隐私泄露风险。

完整代码实现

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <title>Canvas 图片中间水印</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
      background: #f5f5f7;
      padding: 24px;
      margin: 0;
    }
    .container {
      max-width: 720px;
      margin: 0 auto;
      background: #fff;
      padding: 20px;
      border-radius: 16px;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06);
    }
    h2 {
      margin: 0 0 16px;
      font-size: 18px;
    }
    .controls {
      display: flex;
      flex-wrap: wrap;
      gap: 12px;
      align-items: center;
      margin-bottom: 16px;
    }
    .result {
      margin-top: 16px;
      text-align: center;
    }
    canvas {
      max-width: 100%;
      border-radius: 12px;
      border: 1px solid #eee;
      background: #fafafa;
    }
  </style>
</head>
<body>
  <div class="container">
    <h2>上传图片自动添加中间水印</h2>
    <div class="controls">
      <input type="file" id="fileInput" accept="image/*" />
    </div>
    <div class="result">
      <canvas id="canvas"></canvas>
    </div>
  </div>
  <script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    // 上传图片后自动绘制水印
    document.getElementById('fileInput').addEventListener('change', function (e) {
      const file = e.target.files[0];
      if (!file) return;
      const reader = new FileReader();
      reader.onload = function (event) {
        const img = new Image();
        img.onload = function () {
          canvas.width = img.width;
          canvas.height = img.height;
          // 绘制原图
          ctx.drawImage(img, 0, 0);
          // 固定水印参数,取消旋转
          const text = '水印';
          const fontSize = Math.round(Math.min(img.width, img.height) * 0.06);
          const alpha = 0.35;
          ctx.save();
          ctx.globalAlpha = alpha;
          ctx.font = `bold ${fontSize}px -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif`;
          ctx.fillStyle = '#ffffff';
          const textWidth = ctx.measureText(text).width;
          const centerX = canvas.width / 2;
          const centerY = canvas.height / 2;
          // 直接在画布正中间绘制文字,不再旋转
          ctx.fillText(text, centerX - textWidth / 2, centerY);
          ctx.restore();
        };
        img.src = event.target.result;
      };
      reader.readAsDataURL(file);
    });
  </script>
</body>
</html>

关键技术解析

图片读取与画布适配

利用 FileReader 读取本地文件,在图片异步加载完成(onload)后,将 Canvas 宽高同步设置为图片实际像素尺寸。此举彻底解决了因画布尺寸不匹配导致的图片拉伸或变形问题,确保水印绘制精准。

自适应水印字号算法

采用Math.min(img.width, img.height) * 0.06算法,取图片短边的 6% 作为字号基准。该逻辑完美适配横图、竖图及方形图,避免大图水印过小或小图水印溢出的视觉失衡。

居中绘制核心逻辑

摒弃复杂的坐标系旋转与位移计算,直接通过测量文字宽度计算偏移量,实现文字在画布正中心的精准定位。样式简洁干净,符合主流平台的轻量化审美需求。

半透明水印优化

设置globalAlpha = 0.35为黄金透明度参数。该数值既能有效标识版权、防止盗用,又不会过度遮挡图片主体内容,兼顾实用性与美观度。

开发避坑指南

必须在 img.onload 中执行绘制

图片加载属于异步操作,若未等待加载完成直接绘制,会导致画布空白。所有绘图逻辑必须置于图片加载完成的回调函数内。

禁止用 CSS 控制 Canvas 宽高

Canvas 的widthheight属性决定画布像素尺寸,而 CSS 仅控制显示缩放。若仅通过 CSS 设置宽高,会导致渲染模糊及水印失真,必须通过 JS 设置属性值。

save()/restore() 状态隔离

使用ctx.save()ctx.restore()包裹绘图状态修改(如透明度、字体),可防止水印样式污染后续画布操作,提升代码的可复用性与扩展性。

方案总结

该原生 Canvas 水印方案以极简、稳定、高效为核心优势。通过去除冗余交互与配置,实现了“上传即水印”的流畅体验。相较于复杂的开源插件,该方案体积更小、兼容性更强且维护成本低,是中小型项目进行图片版权防护的理想轻量化选择。

【声明】内容源于网络
0
0
wordpress知识
各类跨境出海行业相关资讯
内容 354
粉丝 0
wordpress知识 各类跨境出海行业相关资讯
总阅读10.1k
粉丝0
内容354