vue 图片添加水印

·  阅读 1504

1、用canvas实现图片添加水印

方法注解:

  • getContext:返回一个用于在画布上绘图的环境。

语法:Canvas.getContext(contextID)

参数:contextID 指定了您想要在画布上绘制的类型。当前唯一的合法值是 "2d",它指定了二维绘图,并且导致这个方法返回一个环境对象,该对象导出一个二维绘图 API。

  • drawImage:在画布上绘制图像、画布或视频。也能够绘制图像的某些部分,以及/或者增加或减少图像的尺寸。

语法1:context.drawImage(img,x,y)————在画布上定位图像

语法2:context.drawImage(img,x,y,width,height)————在画布上定位图像,并规定图像的宽度和高度

语法3:context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height)————剪切图像,并在画布上定位被剪切的部分

参数值:

参数描述
img规定要使用的图像、画布或视频。
sx可选。开始剪切的 x 坐标位置。
sy可选。开始剪切的 y 坐标位置。
swidth可选。被剪切图像的宽度。
sheight可选。被剪切图像的高度。
x在画布上放置图像的 x 坐标位置。
y在画布上放置图像的 y 坐标位置。
width可选。要使用的图像的宽度。(伸展或缩小图像)
height可选。要使用的图像的高度。(伸展或缩小图像)
  • fillText:在画布上绘制填色的文本。文本的默认颜色是黑色。

语法:context.fillText(text,x,y,maxWidth)

参数值:

参数描述
text规定在画布上输出的文本。
x开始绘制文本的 x 坐标位置(相对于画布)。
y开始绘制文本的 y 坐标位置(相对于画布)。
maxWidth可选。允许的最大文本宽度,以像素计。
  • rotate:旋转当前的绘图。

语法:context.rotate(angle)

参数值:

参数描述
angle旋转角度,以弧度计。如需将角度转换为弧度,请使用 degrees*Math.PI/180 公式进行计算。举例:如需旋转 5 度,可规定下面的公式:5 * Math.PI/180。
  • toDataURL:返回一个包含图片展示的 数据 URI,图像基于Base64编码

语法:canvas.toDataURL(type, encoderOptions);

参数值:

参数描述
type可选。图片格式,默认为 image/png。(image/png、image/jpeg、image/webp)
encoderOptions可选。图片质量。在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将使用默认值 0.92。其他参数会被忽略。
  • toBlob:创造Blob对象,用以展示canvas上的图片

语法:canvas.toBlob(callback, type, encoderOptions)

参数值:

参数描述
callback回调函数,可获得一个单独的Blob对象参数。
type可选。图片格式,默认为 image/png。(image/png、image/jpeg、image/webp)
encoderOptions可选。图片质量。在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将使用默认值 0.92。其他参数会被忽略。

具体实现方法

  • 单独一个水印

<template>
  <div class=''>
    <img src="@/assets/bg.png" alt="" ref="imageCon">
    <button @click="handleAddWaterMarker">添加水印</button>
    <img :src="image" alt="">
  </div>
</template>

<script>
export default {
  data () {
    return {
      image: "",
    }
  },
  methods: {
    handleAddWaterMarker () {
      let content = "我就是一个水印";
      let imageCon = this.$refs.imageCon;//获取图片
      let canvas = document.createElement("canvas");//创建canvas容器
      canvas.width = imageCon.width;//设置canvas容器宽度
      canvas.height = imageCon.height;//设置canvas容器高度

      let ctx = canvas.getContext("2d");//获取2d画笔

      //在canvas画布上绘制图片 ctx.drawImage(图片, x位置, y位置,  图像宽度, 图像高度);
      ctx.drawImage(imageCon, 0, 0, imageCon.width, imageCon.height);

       //设置文本画笔的样式
      ctx.textAlign = 'left';//设置文本对齐方式
      ctx.textBaseline = 'top';//设置文本基线
      ctx.font = "14px Microsoft Yahei";//设置文本字体属性
      ctx.fillStyle = "rgba(255, 255, 255,0.25)"//设置文本字体颜色
      
      //在canvas画布上绘制文字 ctx.fillText(文字内容, x位置, y位置, 文本最大宽度)
      ctx.fillText(content, imageCon.width - (content.split("").length * 14 + 10), imageCon.height - (14 + 10), imageCon.width)//14为文字大小
      
      this.image = canvas.toDataURL("image/png");//把canvas转base64输出
    }
  },
}
</script>
复制代码

效果: image.png

  • 水印铺满图片

<template>
  <div class=''>
    <img src="@/assets/bg.png" alt="" ref="imageCon">
    <button @click="handleAddWaterMarker">添加水印</button>
    <img :src="image" alt="">
  </div>
</template>

<script>
export default {
  components: {},
  props: {},
  data () {
    return {
      image: "",
    }
  },
  methods: {
    handleAddWaterMarker () {
      let content = "我就是一个水印";
      let height = 80; //两个水印之间的垂直高度
      let width = 70; //两个水印之间的水平高度
      let fontSize = 14; //水印字体大小
      let imageCon = this.$refs.imageCon;//获取图片
      let canvas = document.createElement("canvas");//创建canvas容器
      canvas.width = imageCon.width;//设置canvas容器宽度
      canvas.height = imageCon.height;//设置canvas容器高度

      let ctx = canvas.getContext("2d");//获取2d画笔

      //在canvas画布上绘制图片 ctx.drawImage(图片, x位置, y位置,  图像宽度, 图像高度);
      ctx.drawImage(imageCon, 0, 0, imageCon.width, imageCon.height);

      //设置文本画笔样式
      ctx.textAlign = 'left';//设置文本对齐方式
      ctx.textBaseline = 'top';//设置文本基线
      ctx.font = `${fontSize}px Microsoft Yahei`;//设置文本字体属性
      ctx.fillStyle = "rgba(255, 255, 255,0.25)"//设置文本字体颜色

      //在canvas画布上绘制文字 ctx.fillText(文字内容, x位置, y位置, 文本最大宽度)
      ctx.rotate(17 * Math.PI / 180)//文本旋转角度设置
      let i = 0, j = 0, waterMarkerWidth = content.split("").length * fontSize;
      for (i = 0; i < imageCon.width / (waterMarkerWidth); i++) {
        for (j = 0; j < imageCon.height / (height - 20); j++) {
          if (j == 0) {
            ctx.fillText(content, i * (waterMarkerWidth + width), -height, imageCon.width)
          }
          ctx.fillText(content, i * (waterMarkerWidth + width), j * height, imageCon.width)
        }
      }

      // var image = new Image();
      // imageCon.setAttribute('crossOrigin', 'anonymous');//跨域
      // imageCon.setAttribute('useCORS', true);//跨域
      // image.setAttribute('crossOrigin', 'anonymous');//跨域
      // image.setAttribute('useCORS', true);//跨域
      // image.src = canvas.toDataURL("image/png");
      this.image = canvas.toDataURL("image/png");//把canvas转base64输出
    }
  },
}
</script>

<style lang="less"  scoped>
</style>
复制代码

效果: image.png

image.png

2、利用dom-to-image实现图片添加水印

方法注解

  • encodeURIComponent:把字符串作为 URI 组件进行编码。

语法:encodeURIComponent(uri)

参数值:

参数描述
uri必需。一个字符串,含有 URI 组件或其他要编码的文本。
  • unescape:对编码的字符串进行解码。

语法:unescape(string)

参数值:

参数描述
string必需。要解码的字符串。
  • btoa:用于创建一个 base-64 编码的字符串。【base-64 解码使用方法是 atob() 】。

语法:window.btoa(string)

参数值:

参数描述
string必需,要编码的字符串。

具体实现方法

<template>
  <div class="">
    <!-- 转换水印前html -->
    <div class="preview" ref="previewImg">
      <img :src="defaultimg" alt="" />
      <div class="watermark" :style="{ background: watermark }"></div>
    </div>
    <button @click="handleAddWaterMarker">添加水印</button>
    <!-- 转换成水印后 -->
    <img :src="image" alt="">
  </div>
</template>
<script>
import DomToImage from "dom-to-image";
export default {
  data () {
    return {
      defaultimg: require("@/assets/bg.png"),
      watermark: "",
      image: "",
      watermarkOptions: {
        text: "我就是一个水印",
        fontSize: 12,
        width: 20,
        color: "#fff",
        alpha: 20,
        rotate: 35
      }
    };
  },
  methods: {
    handleAddWaterMarker () {
      // 文字长度
      const wordWidth = this.watermarkOptions.fontSize * this.watermarkOptions.text.split("").length;
      const width = wordWidth + this.watermarkOptions.width;

      let svgText = `
      <svg xmlns="http://www.w3.org/2000/svg" width="${width}px" height="${width}px">
        <text x="50%" y="50%"
          alignment-baseline="middle"
          text-anchor="middle"
          stroke="${this.watermarkOptions.color}"
          opacity="${this.watermarkOptions.alpha / 100}"
          transform="translate(${width / 2}, ${width / 2}) rotate(${this.watermarkOptions.rotate}) translate(-${width / 2}, -${width / 2})"
          font-weight="100"
          font-size="${this.watermarkOptions.fontSize}"
          font-family="microsoft yahe"
          >
          ${this.watermarkOptions.text}
        </text>
      </svg>`;
      this.watermark = `url(data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(svgText)))})`;

      // 把html转换为图片
      let node = this.$refs.previewImg, that = this;
      DomToImage.toPng(node).then((dataUrl) => {
        that.image = dataUrl;
      });
    }
  },
};
</script>

<style lang="less" scoped>
.preview {
  display: inline-block;
  position: relative;
  margin-left: 20px;
  width: 375px;
  height: 668px;
  img {
    display: block;
  }
  .watermark {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    right: 0;
  }
}
</style>
复制代码

效果:

image.png

分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改