canvas 添加文字水印、图片水印并实现图片水印透明

这篇博客介绍了如何利用HTML5的Canvas API在图片上添加文字水印和图片水印。首先展示了如何添加文字水印,通过设置字体、颜色和位置。然后详细解释了添加图片水印的过程,包括透明度控制和多水印定位。最后提供了完整的代码示例,演示了如何在实际开发中应用这些方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先上效果图

1、图片添加文字

在这里插入图片描述

2、图片添加图片水印

在这里插入图片描述

1、图片添加文字水印

    async init() {
      let imgUrl =
        "http://qysmjczto.hn-bkt.clouddn.com/37c1ed77-f934-4bd9-bc50-c7160decab5c.png";
      const img = await this.loadImage(imgUrl);
      const canvas = document.createElement("canvas");
      const imgRatio = img.naturalWidth / img.naturalHeight;
      const ctxWidth = 400;
      const ctxHeight = ctxWidth / imgRatio;
      canvas.width = ctxWidth;
      canvas.height = ctxHeight;
      const ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0, 0, ctxWidth, ctxHeight);
      const res = await this.watermark(canvas, "wf_cs");
    },
    loadImage(src) {
      return new Promise((resolve, reject) => {
        let img = new Image();
        if (src.indexOf(src) === 0) {
          img.crossOrigin = "*"; // 处理跨域
        }
        img.src = src;
        img.onload = () => {
          resolve(img);
        };
        img.onerror = () => {
          reject(new Error("图片解析失败"));
        };
      });
    },
    watermark(canvas, text) {
      return new Promise((resolve, reject) => {
        let ctx = canvas.getContext("2d");
        ctx.font = "22px";
        ctx.fillStyle = "blue";
        ctx.textAlign = "right";
        ctx.fillText(text, canvas.width - 20, canvas.height - 30);
        // 多行文本 可自行抽离成方法
        // ctx.font = "12px 宋体";
        // ctx.fillStyle = "red";
        // ctx.textAlign = "right";
        // let date = new Date().getTime();
        // ctx.fillText(date, canvas.width - 20, canvas.height - 20);
        resolve(canvas.toDataURL("image/png", 1));
      });
    }

2、添加图片水印

  1. 方法实现原理为canvas上进行图片的叠加
  2. 因为需要水印透明,因此建议先生成水印再生成地图,避免把底图也透明了
  3. 考虑到水印一般会出现多个,因此抽离出addImageWatermark方法,该方法控制水印的位置大小等,实际开发请根据图片的大小自行计算传入的x y值
    async init() {
     const img = await this.loadImage(require("../../assets/canvas.png"));
     const img2 = await this.loadImage(require("../../assets/test.png"));
     const canvas = document.createElement("canvas");
     const imgRatio = img2.naturalWidth / img2.naturalHeight;
     const ctxWidth = 400;
     const ctxHeight = ctxWidth / imgRatio;
     canvas.width = ctxWidth;
     canvas.height = ctxHeight;
     const ctx = canvas.getContext("2d");
     for (var i = 0; i < 5; i++) {
       this.addImageWatermark(ctx, img, 40 * (i + 1) + 5, 80, 40, 40);
     }
     await this.watermark(canvas, "这是文字水印");
     ctx.drawImage(img2, 0, 0, ctxWidth, ctxHeight);
     this.newImage = canvas.toDataURL("image/jpg", 1);
   },
    /**
    * @param{ctx} canvas创建的画布环境
    * @param{img} loadImage方法返回的图片
    * @param{x} 水印绘画的x轴位置
    * @param{y} 水印绘画的y轴位置
    * @param{width} 水印宽度
    * @param{height} 水印高度
    */
   async addImageWatermark(ctx, img, x, y, width, height) {
     ctx.drawImage(img, x, y, width, height);
     let imgData = ctx.getImageData(x, y, width, height);
     for (var i = 0, len = imgData.data.length; i < len; i += 4) {
       imgData.data[i + 3] = imgData.data[i + 3] * 0.1;
     }
     ctx.putImageData(imgData, x, y);
   },
   loadImage(src) {
     return new Promise((resolve, reject) => {
       let img = new Image();
       if (src.indexOf(src) === 0) {
         img.crossOrigin = "*";
       }
       img.src = src;
       img.onload = () => {
         resolve(img);
       };
       img.onerror = () => {
         reject(new Error("图片解析失败"));
       };
     });
   },
   watermark(canvas, text) {
     return new Promise((resolve, reject) => {
       let ctx = canvas.getContext("2d");
       ctx.font = "22px";
       ctx.fillStyle = "blue";
       ctx.textAlign = "right";
       ctx.fillText(text, canvas.width - 20, canvas.height - 30);
       ctx.font = "12px 宋体";
       ctx.fillStyle = "red";
       ctx.textAlign = "right";
       let date = new Date().getTime();
       ctx.fillText(date, canvas.width - 20, canvas.height - 20);
       resolve(canvas.toDataURL("image/png", 1));
     });
   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值