Demo: 给图片添加自定义水印并下载

给图片添加自定义水印并下载

javascript 复制代码
<template>
  <div class="wrap">
    <div class="optea">
      <p>水印文字</p>
      <el-input v-model="watermarkOptions.text" placeholder="请输入水印内容"></el-input>
      <p>字体颜色</p>
      <el-color-picker v-model="watermarkOptions.color"></el-color-picker>
      <p>旋转角度</p>
      <el-slider v-model="watermarkOptions.rotate" :min="0" :max="360"></el-slider>
      <p>透明度</p>
      <el-slider v-model="watermarkOptions.alpha" :min="0" :max="100"></el-slider>
      <p>文本间距</p>
      <el-slider v-model="watermarkOptions.width" :min="0" :max="100"></el-slider>
      <p>字体大小</p>
      <el-slider v-model="watermarkOptions.fontSize" :min="0" :step="0.5" :max="50"></el-slider>
    </div>
    <div class="previewImage">
      <el-button
        @click="handleDown"
        class="download-btn"
        type="primary"
        plain
        icon="el-icon-download"
        >下载水印图片</el-button
      >
      <div class="preview" ref="previewImg">
        <img :src="preImg" alt="" />
        <div class="watermark" :style="{ background: paint }"></div>
      </div>
    </div>
  </div>
</template>
<script setup>
import DomToImage from 'dom-to-image'
import { ref, reactive, computed } from 'vue'

const previewImg = ref(null)
const watermarkOptions = reactive({
  text: '仅供 xxx 验证使用',
  fontSize: 10,
  width: 5,
  color: '#000000',
  alpha: 35,
  rotate: 35
})

defineProps({
  preImg: {
    type: String,
    default: ''
  }
})

const handleDown = () => {
  let node = previewImg.value
  DomToImage.toPng(node)
    .then(function (dataUrl) {
      var oLink = document.createElement('a')
      oLink.download = '水印图片.png'
      oLink.href = dataUrl
      oLink.click()
    })
    .catch(function (error) {
      console.error('oops, something went wrong!', error)
    })
}

const paint = computed(() => {
  const wordWidth = watermarkOptions.fontSize * watermarkOptions.text.split('').length
  const width = wordWidth + 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="${watermarkOptions.color}"
        opacity="${watermarkOptions.alpha / 100}"
        transform="translate(${width / 2}, ${width / 2}) rotate(${
          watermarkOptions.rotate
        }) translate(-${width / 2}, -${width / 2})"
        font-weight="100"
        font-size="${watermarkOptions.fontSize}"
        font-family="microsoft yahe"
        >
        ${watermarkOptions.text}
    </text>
   </svg>`
  return `url(data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(svgText)))})`
})
</script>

<style lang="scss" scoped>
.wrap {
  padding: 10px 20px;
  display: flex;
  justify-content: flex-start;
  align-items: center;

  .optea {
    // width: 500px;
    margin-right: 20px;

    p {
      margin: 5px 0;
      margin-bottom: 10px;
      font-weight: 600;
    }
  }

  .previewImage {
    .download-btn {
      margin: 0 15px 15px;
    }

    .preview {
      position: relative;
      min-width: 520px;
      max-height: 800px;

      img {
        width: 100%;
        max-height: 800px;
      }

      .watermark {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
      }
    }
  }
}
</style>
相关推荐
思茂信息7 分钟前
CST电动车EMC仿真(二)——电机控制器MCU的EMC仿真
开发语言·javascript·单片机·嵌入式硬件·cst·电磁仿真
晴殇i10 分钟前
前端极速性能优化:从加载到渲染的全链路实战指南
前端·javascript
AAA阿giao12 分钟前
JavaScript 深拷贝全解析:从栈与堆内存机制到安全对象复制实践
前端·javascript·json
AAA阿giao17 分钟前
深入理解 JavaScript 的 Array.prototype.map() 方法及其经典陷阱:从原理到面试实战
前端·javascript·面试
开始了码31 分钟前
关于qt运行程序点击几下未响应的原因
开发语言·qt
Kimser32 分钟前
QT C++ QWebEngine与Web JS之间通信
javascript·c++·qt
QT 小鲜肉32 分钟前
【QT/C++】Qt样式设置之CSS知识(系统性概括)
linux·开发语言·css·c++·笔记·qt
洛克希德马丁38 分钟前
Qt配置安卓开发环境
android·开发语言·qt
我要升天!39 分钟前
QT-- 理解项目文件
开发语言·数据库·qt
froginwe111 小时前
Ruby 范围(Range)
开发语言