vue中使用canvas添加各类水印

本文详细介绍了如何在Vue应用中使用canvas绘制文字水印和图片水印,包括创建watermarker.js模块、在模板中调用方法、以及处理图片合成操作。通过实例展示,读者可以掌握在网页中添加视觉效果的方法。

vue使用canvas绘制文字水印背景

1、写watermarker.js文件

/**  水印添加方法  */

const setWatermark = (str1, str2) => {
  const id = '1.23452384164.123412415'

  if (document.getElementById(id) !== null) {
    document.body.removeChild(document.getElementById(id))
  }

  const can = document.createElement('canvas')
  // 设置canvas画布大小
  can.width = 150
  can.height = 80

  const cans = can.getContext('2d')
  cans.rotate(-20 * Math.PI / 180) // 水印旋转角度
  cans.font = '15px Vedana'
  cans.fillStyle = '#666666'
  cans.textAlign = 'center'
  cans.textBaseline = 'Middle'
  cans.fillText(str1, can.width / 2, can.height) // 水印在画布的位置x,y轴
  cans.fillText(str2, can.width / 2, can.height + 22)

  const div = document.createElement('div')
  div.id = id
  div.style.pointerEvents = 'none'
  div.style.top = '40px'
  div.style.left = '0px'
  div.style.opacity = '0.15'
  div.style.position = 'fixed'
  div.style.zIndex = '100000'
  div.style.width = document.documentElement.clientWidth + 'px'
  div.style.height = document.documentElement.clientHeight + 'px'
  div.style.background = 'url(' + can.toDataURL('image/png') + ') left top repeat'
  document.body.appendChild(div)
  return id
}

// 添加水印方法
export const setWaterMark = (str1, str2) => {
  let id = setWatermark(str1, str2)
  if (document.getElementById(id) === null) {
    id = setWatermark(str1, str2)
  }
}

// 移除水印方法
export const removeWatermark = () => {
  const id = '1.23452384164.123412415'
  if (document.getElementById(id) !== null) {
    document.body.removeChild(document.getElementById(id))
  }
}

2、在页面中使用

<template>
  <div>
  </div>
</template>

<script>
import { removeWatermark, setWaterMark } from '../utils/watermaker'

export default {
  name: 'TestWaterMaker',
  mounted () {
    setWaterMark('liergou', '李二狗')
  },
  destroyed () {
    removeWatermark()
  }
}
</script>

<style scoped>

</style>

效果图如下

2、图片添加文字水印

<template>
  <div>
    <input type="file" id="uploadFile" class="clip" accept="image/*" @change="chooseImg">
    <input type="text" placeholder="请输入你要添加的水印文字" class="water-text" v-model="text" @change="conformText()">
    <div>
      <img id="imgsrc" :src="imgsrc" :width="size">
      <img id="imgTextUrl" :src="imgTextUrl" :width="size"><br/>
      下载
      <img id="imgUploadUrl" :src="imgUploadUrl" @click="downLoad()"><br/>
      <div class="conform" @click="confirmImg()">合成图片</div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'TestWaterMaker1',
  data () {
    return {
      imgsrc: '',
      text: '',
      size: 180,
      imgTextUrl: '',
      imgUploadUrl: ''
    }
  },
  methods: {
    // 上传图片
    chooseImg (event) {
      var file = event.target.files[0]
      var reader = new FileReader()
      reader.readAsDataURL(file)
      const _this = this
      reader.onload = function () {
        _this.imgsrc = reader.result
      }
      _this.imgsrc = file
    },
    // 生成水印文字 canvas文字你可以设置为你喜欢的样式
    conformText () {
      var canvas = document.createElement('canvas') // 准备空画布
      var ctx = canvas.getContext('2d')
      ctx.font = '20px Georgia' // canvas字体
      ctx.fillText(this.text, 10, 50)
      var gradient = ctx.createLinearGradient(0, 0, canvas.width, 0)
      gradient.addColorStop('0', 'magenta')
      gradient.addColorStop('0.5', 'blue')
      gradient.addColorStop('1.0', 'red')
      ctx.fillStyle = gradient
      this.imgTextUrl = canvas.toDataURL('image/png')
    },
    // 合成图片
    confirmImg (url) {
      var canvasAll = document.createElement('canvas')
      // const size = 180
      canvasAll.width = this.size
      canvasAll.height = this.size
      var context = canvasAll.getContext('2d')

      // 这是上传图像
      var imgUpload = new Image()
      var img1 = document.getElementById('imgsrc')
      var img2 = document.getElementById('imgTextUrl')
      context.drawImage(img1, 0, 0, img1.width, img1.height)
      // 再次绘制
      context.drawImage(img2, 0, 130, img2.width, img2.height)
      const that = this
      imgUpload.src = url
      that.imgUploadUrl = canvasAll.toDataURL('image/png')
      /* imgUpload.onload = function () {
        // 绘制
        context.drawImage(img1, 0, 0, img1.width, img1.height)
        // 再次绘制
        context.drawImage(img2, 0, 130, img2.width, img2.height)
        // 回调
        that.imgUploadUrl = canvasAll.toDataURL('image/png')
        console.info(that.imgUploadUrl)
      } */
    },
    downLoad () {
      var a = document.createElement('a')
      a.href = this.imgUploadUrl // 将画布内的信息导出为png图片数据
      a.download = '水印图片' // 设定下载名称 如果不设置a.download 浏览器会尝试打开这张图片 而图片会下载失败
      a.click() // 点击触发下载
    }
  }
}
</script>

<style scoped>

</style>

3、图片添加图片水印

例子两张图片叠加在一起

mounted () {
    const img1 = new Image()
    const that = this
    img1.src = 'data:image/png;base64.........'
    img1.onload = function () {
      const img2 = new Image()
      img2.src = 'data:image/png;base64.........'
      img2.onload = function () {
        const can = document.createElement('canvas')
        can.width = 1080
        can.height = 1080
        const cans = can.getContext('2d')
        cans.drawImage(img1, 0, 0, img1.width, img1.height)
        cans.drawImage(img2, 0, 0, img2.width, img2.height)
        that.imgUploadUrl = can.toDataURL('image/png')
      }
    }
  }

 

<think>我们正在处理一个在Vue2中使用Canvas图片添加水印的需求。根据引用内容,我们可以采用以下方法:方法1:动态生成水印背景图(引用[1])——将水印作为背景图重复平铺。方法2:在图片上绘制水印(引用[2]和[3])——将图片水印都绘制到同一个Canvas上。用户需求是给图片添加水印,而不是作为背景,因此方法2更合适。步骤:1.在Vue组件中,创建一个canvas元素,并获取其上下文。2.载原始图片。3.图片载完成后,在canvas上绘制图片(等比例缩放至合适大小)。4.在图片上绘制水印(可以是文字或图片水印,重复平铺或指定位置)。5.将canvas转换为图片并显示。根据引用[3]的示例,我们可以绘制文字水印,并重复平铺。注意:由于canvas的绘制是异步的(图片载),我们需要在图片载完成后再绘制水印。我们将创建一个Vue2组件,包含以下部分:- template:包含canvas元素(用于绘制)和img元素(用于显示结果,可选)或直接使用canvas显示。- script:实现绘制逻辑。示例代码(基于引用[3]调整):-使用`<canvas>`元素,并设置ref以便访问。-在mounted或方法中调用绘制函数。但是注意:用户可能希望上传图片,因此我们还需要处理图片上传的情况。这里我们先假设图片路径已知。为了更通用,我们可以通过props传入图片路径,然后绘制。组件设计:-属性:src(图片路径),watermarkText(水印文字)-数据:无(或保存生成的图片URL,用于显示)-方法:drawImageWithWatermark由于在Vue2中,我们使用this.$refs来访问canvas。代码示例:注意:由于canvas的绘制需要图片完全载,所以我们在mounted钩子中开始绘制,或者当src变化时重新绘制。我们将创建一个组件,并在mounted中调用绘制方法。如果图片路径可能变化,需要监听src的变化。另外,为了不阻塞页面,使用img.onload异步处理。步骤详解:1.创建Image对象,设置src为传入的图片路径。2.图片载完成后,获取canvas的context。3.设置canvas的宽高为图片的宽高(或者根据需求调整,比如固定宽高,保持比例)。4.绘制图片canvas上(可以等比例缩放)。5.设置水印样式(字体、颜色、旋转等)。6.重复绘制水印文字(使用循环,在图片上平铺)。7.如果需要,可以将canvas转换为图片URL,并设置为img的src(或者直接显示canvas)。注意:如果图片跨域,需要处理跨域问题(图片服务器允许跨域)。下面我们写一个简单的组件代码:</think>在 Vue2 中使用 Canvas图片添加水印,可以通过以下步骤实现: ### 实现步骤 1. **准备画布**:创建 `<canvas>` 元素并获取 2D 上下文 2. **图片**:使用 `Image` 对象载原始图片 3. **绘制图片**:将图片绘制到画布上 4. **添加水印**:在图片上绘制文字水印(可旋转、平铺) 5. **导出结果**:将画布转换为图片并显示 ### 示例代码 ```html <template> <div> <!-- 原始图片 --> <img :src="originalImage" v-if="originalImage" style="max-width: 100%"> <!-- 带水印的结果 --> <img :src="watermarkedImage" v-if="watermarkedImage"> <!-- 画布(隐藏) --> <canvas ref="canvas" style="display:none"></canvas> </div> </template> <script> export default { data() { return { originalImage: "https://example.com/your-image.jpg", // 替换为你的图片URL watermarkedImage: null }; }, mounted() { this.addWatermark(); }, methods: { addWatermark() { const canvas = this.$refs.canvas; const ctx = canvas.getContext('2d'); // 载原始图片 const img = new Image(); img.crossOrigin = "Anonymous"; // 处理跨域问题 img.src = this.originalImage; img.onload = () => { // 设置画布尺寸与图片一致 canvas.width = img.width; canvas.height = img.height; // 绘制原始图片 ctx.drawImage(img, 0, 0, img.width, img.height); // 设置水印样式 ctx.font = "30px Microsoft YaHei"; ctx.fillStyle = "rgba(255, 255, 255, 0.5)"; ctx.textAlign = "center"; ctx.textBaseline = "middle"; // 添加平铺水印(5行5列) const watermarkText = "机密水印"; const textWidth = ctx.measureText(watermarkText).width; for (let row = 0; row < 5; row++) { for (let col = 0; col < 5; col++) { ctx.save(); // 保存当前状态 ctx.translate(col * (img.width / 4), row * (img.height / 4)); ctx.rotate(-45 * Math.PI / 180); // 旋转45度 ctx.fillText(watermarkText, 0, 0); ctx.restore(); // 恢复状态 } } // 转换为图片URL this.watermarkedImage = canvas.toDataURL("image/png"); }; img.onerror = (e) => { console.error("图片载失败", e); }; } } }; </script> ``` ### 关键说明 1. **跨域处理**: - 若图片来自不同域名,需设置 `img.crossOrigin = "Anonymous"` - 确保图片服务器支持 CORS 2. **水印样式**: - 透明度:通过 `rgba(255,255,255,0.5)` 的第四个参数控制 - 旋转角度:`ctx.rotate(-45 * Math.PI/180)` 实现 -45 度倾斜 - 平铺密度:调整循环中的 `row` 和 `col` 数量 3. **性能优化**: - 大图片建议先压缩尺寸 - 复杂水印使用离屏渲染 ### 注意事项 1. 文字水印需考虑字体兼容性,建议使用通用字体 2. 对于动态内容,可封装为可复用组件 3. 重要场景建议添加服务端水印验证[^1] ### 备选方案 若需添加图片水印(非文字),可替换绘制部分: ```javascript const watermarkImg = new Image(); watermarkImg.src = "watermark.png"; watermarkImg.onload = () => { ctx.drawImage( watermarkImg, xPosition, yPosition, width, height ); }; ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值