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

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

在这里插入图片描述

<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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/323805.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LInux初学之路linux的磁盘分区/远程控制/以及关闭图形界面/查看个人身份

虚拟机磁盘分配 hostname -I 查看ip地址 ssh root虚拟就ip 远程连接 win10之后才有 远程控制重新启动 reboot xshell 使用&#xff08;个人和家庭版 免费去官方下载&#xff09; init 3 关闭界面 减小内存使用空间 init 5 回复图形界面 runlevel显示的是状态 此时和上…

重学Java 6 流程控制语句

我与我&#xff0c;至死不渝 ——24.1.15 模块重点&#xff1a; ①会使用Scanner和Random ②会使用switch以及知道case的穿透性 ③会使用if ④会使用for循环&#xff0c;while循环&#xff0c;嵌套循环 一、键盘录入_Scanner 1.概述&#xff1a;是Java定义好的一个类 2.作用&am…

前端学习路径

菜鸟感觉很多人不太知道菜鸟写的博客是一个可以跟着学习、一起深入理解的过程&#xff0c;其中包括了菜鸟从刚开始学习到后面重新学习&#xff0c;再到后面进入学框架等一系列学习过程、知识和感悟&#xff0c;所以菜鸟把自己的博客整理成一个目录提取出来&#xff0c;好让读者…

kafka系列(二)

本章承接kafka一内容&#xff0c;文章在本人博客主页都有&#xff0c;可以自行点击浏览。 幂等性 请求执行多次&#xff0c;但执行的结果是一致的。 如果&#xff0c;某个系统是不具备幂等性的&#xff0c;如果用户重复提交了某个表格&#xff0c;就可能会造成不良影响。例如…

OpenHarmony——Linux之IR驱动

Linux之IR驱动 背景 在光谱中波长自760nm至400um的电磁波称为红外线&#xff0c;它是一种不可见光。红外遥控成本很低&#xff0c;以前广泛应用在电视&#xff0c;空调等电器的控制上面&#xff0c;现在随着蓝牙遥控器慢慢普及&#xff0c;红外遥控越来越少&#xff0c;但在某…

确定性网络技术怎样实现网络的可靠性?

确定性网络技术通过采用特定的协议、机制和策略&#xff0c;有助于提高网络的可靠性。本文通过一些关键的方面&#xff0c;来说明确定性网络技术如何实现这一目标。 时钟同步机制 时钟同步机制是确定性网络中的核心角色。为了实现高度可靠的通信&#xff0c;需要采用先进的时钟…

运筹说 第65期 | 动态规划的基本概念和基本原理

20世纪50年代初&#xff0c;美国数学家R. Bellman 等人在解决多阶段决策优化问题时提出了一种高效的求解方法——动态规划&#xff08;Dynamic Programming&#xff09;&#xff0c;该方法基于多阶段决策优化问题的特点&#xff0c;把多阶段问题转换为一系列互相联系的单阶段问…

档案数字化加工是如何利用档案的

档案数字化加工是通过将实体档案转化为电子形式&#xff0c;利用数字化技术对档案进行处理和管理。这样做可以带来以下几个方面的利益&#xff1a; 1. 提高档案的可访问性&#xff1a;数字化档案可以轻松存储在电脑或云存储中&#xff0c;可以随时随地通过计算机或移动设备访问…

HNU-算法设计与分析-实验3

算法设计与分析实验3 计科210X 甘晴void 202108010XXX 目录 文章目录 算法设计与分析<br>实验31 用Dijkstra贪心算法求解单源最短路径问题问题重述证明模板&#xff1a;Dijkstra算法代码验证算法分析 1【扩展】 使用堆优化的Dijkstra原因代码算法分析验证 2 回溯法求解…

[docker] Compose 简介

文章目录 Compose 简介Compose 安装1、使用二进制安装包安装2、用pip安装 使用1、准备2、创建 Dockerfile 文件3、创建 docker-compose.yml4、使用 Compose 命令构建和运行您的应用 yml 配置指令参考versionbuildcap_add&#xff0c;cap_dropcgroup_parentcommandcontainer_nam…

设计模式⑥ :访问数据结构

一、前言 有时候不想动脑子&#xff0c;就懒得看源码又不像浪费时间所以会看看书&#xff0c;但是又记不住&#xff0c;所以决定开始写"抄书"系列。本系列大部分内容都是来源于《 图解设计模式》&#xff08;【日】结城浩 著&#xff09;。该系列文章可随意转载。 …

《C++大学教程》4.34阶乘

题目&#xff1a; 对一个非负整数n来说&#xff0c;它的阶乘可以写成 n! (读作“n的阶乘”)&#xff0c;其计算公式定义如下&#xff1a; n! n x (n-1) x (n-2)x......x1&#xff08;对于大于1的 n &#xff09; 和 n! 1 ( 对于等于0或者等于1的n ) 例如&#xff0c;5&…

【SpringMVC】—— 如何配置使用SpringMVC(详细步骤)

目录 引言 使用 1、新建模块 2、导入坐标 3、创建SpringMVC控制器类 4、初始化SpringMVC环境 5、初始化Servlet容器&#xff0c;加载SpringMVC环境 6、配置运行 引言 SpringMVC是一种基于Java实现MVC模型的轻量级Web框架&#xff0c;SpringMVC是表现层(web层)的框架,也…

Java开发笔记

一、参数校验 1、校验json字符串是否符合规范 &#xff08;1&#xff09;业务场景&#xff1a;接收前端传输过来的json串&#xff0c;需要将其写入数据库&#xff0c;写入之前需要校验其是否能够转换成对应实体类&#xff0c;以便后续从数据库读取   &#xff08;2&#xff0…

条件控制生成---相关论文集合

1. IP-Adapter 论文地址 解决问题&#xff1a; 如何将图片作为prompt输入网络&#xff0c;并无需更改开源模型参数 解决思路&#xff1a; 新增一个cross-attention layers&#xff0c;结果与text prompt的cross-attention layers结果相加后输入网络&#xff0c;只需要训练Wk, …

细说JavaScript对象(JavaScript对象详解)

在JavaScript中对象作为数据类型之一&#xff0c;它的数据结构区别于其余5中数据类型&#xff0c;从数据结构角度看对象就是数据值的几个&#xff0c;其书就结构就是若干组名值对&#xff0c;类似于其他语言中的哈希、散列 关联数组等&#xff0c;但对象在JavaScript中不仅仅扮…

基于Python+Django,我搭建一个视频点播平台

学习过程中&#xff0c;遇到问题可以咨询作者 功能介绍 平台采用B/S结构&#xff0c;后端采用主流的Python语言进行开发&#xff0c;前端采用主流的Vue.js进行开发。 整个平台包括前台和后台两个部分。 前台功能包括&#xff1a;首页、视频列表页面、视频详情页、用户中心模…

VMware workstation安装Fedora-Server-39-1.5虚拟机并配置网络

VMware workstation安装Fedora-Server-39-1.5虚拟机并配置网络 Fedora包含的软件以自由及开放源码许可来发布&#xff0c;并旨在成为该技术领域的领先者。Fedora在专注创新、抢先集成新技术、与上游Linux社区紧密工作方面拥有良好名声。该文档适用于在VMware workstation平台安…

一篇文章掌握负载均衡Ribbon作用和架构以及核心组件

目录 1、Ribbon是什么 2、Ribbon的作用 1.集中式LB 2.进程式LB 3、Ribbon负载均衡架构 总结&#xff1a; 4、Ribbon核心组件IRule 1、Ribbon是什么 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。 简单的说&#xff0c;Ribbon是Netflix发布…

消失的水母-第15届蓝桥第三次STEMA测评Scratch真题精选

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第165讲。 第15届蓝桥杯第3次STEMA测评已于2023年12月17日落下帷幕&#xff0c;编程题一共有6题&#xff0c;分别如下&…