基于canvas实现图片文字水印生成器

news2024/12/23 3:06:35

目录

介绍

1.静态页面结构

2.给生成水印按钮绑定点击事件

3.生成水印的函数

总结


介绍

在前端开发中时常会遇到需要给图片加上水印的功能,就像在创作csdn的文章时上传的图片都会打上传作者的水印,我们来探讨一下这个水印是如何生成的。

 首先生成的文字水印大概可以控制该文字的颜色、字体大小、以及水印的位置等

1.静态页面结构

我们就简单的搭一个水印生成器的静态页面

<!DOCTYPE html>
<html>

<head>
  <title>图片水印生成器</title>
  <style>
    .container {
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    #watermark {
      position: relative;
    }

    #downloadBtn {
      margin-top: 10px;
      padding: 5px 10px;
      background-color: #4CAF50;
      color: white;
      border: none;
      cursor: pointer;
      display: none;
    }
  </style>
</head>

<body>
  <div class="container">
    <h2>图片水印生成器</h2>
    <input type="file" id="fileInput">
    <br>
    <label for="text">水印文字:</label>
    <input type="text" id="text">
    <br>
    <label for="size">文字大小:</label>
    <input type="number" id="size">
    <br>
    <label for="color">文字颜色:</label>
    <input type="color" id="color">
    <br>
    <label for="position">水印位置:</label>
    <select id="position">
      <option value="top-left">左上角</option>
      <option value="top-right">右上角</option>
      <option value="bottom-left">左下角</option>
      <option value="bottom-right">右下角</option>
      <option value="center">居中</option>
    </select>
    <br>
    <button id="generateBtn">生成水印</button>
    <a href="#" id="downloadBtn" download="watermarked_image.png">下载水印图片</a>
    <br>
    <img id="watermark" src="" alt="水印图片">
  </div>
</body>

</html>

静态页面大概是这个样子

接下来就是js代码

2.给生成水印按钮绑定点击事件

 首先要获取到生成水印的按钮给他绑定一个点击事件

  document.getElementById('generateBtn').addEventListener('click', generateWatermark);
    //点击后调用此函数生成水印

3.生成水印的函数

首先要获取到需要用到的值的dom

 const obj = {
        text: document.getElementById('text').value,
        size: document.getElementById('size').value,
        color: document.getElementById('color').value,
        position: document.getElementById('position').value
      }

读取用户上传的图片的文件

const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
const reader = new FileReader(); //获取一个FileReader对象,用于读取上传的图片文件。

绑定文件读取完后的触发的事件

reader.onload = (event) => { //当文件读取完成后触发
        const img = new Image(); //创建一个Image对象,用于加载上传的图片文件
        img.onload = () => { //当图片加载完成后触发
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = img.width; //canvas画布的width和height就是图片的宽和高
        canvas.height = img.height;
        ctx.drawImage(img, 0, 0); //将上传的图片绘制到canvas上
        }
    };

这里就是利用canvas画布来构造,将画布的宽和高就设置为图片的大小,在将图片贴到canvas画布上

 接下来就是设置文字的大小、颜色、位置了

          ctx.font = obj.size + 'px Arial'; //设置canvas上文字的字体大小和颜色
          ctx.fillStyle = obj.color;
          console.log(obj.position);
          switch (obj.position) {
            case 'top-left':
              ctx.fillText(obj.text, 10, 30)
              break
            case 'top-right':
              ctx.fillText(obj.text, canvas.width - 10 - ctx.measureText(obj.text).width, 30)
              break
            case 'bottom-left':
              ctx.fillText(obj.text, 10, canvas.height - 10)
              break
            case 'bottom-right':
              ctx.fillText(obj.text, canvas.width - 10 - ctx.measureText(obj.text).width, canvas.height - 10)
              break
            case 'center':
              const textWidth = ctx.measureText(obj.text).width
              const textHeight = 20 // Assuming font size is 20px
              const centerX = (canvas.width - textWidth) / 2
              const centerY = (canvas.height + textHeight) / 2
              ctx.fillText(obj.text, centerX, centerY)
              break
          }

我的文字位置就设置了四个角落以及中间,这个位置可以根据实际情况决定

文字的位置计算方法也是用了ctx.measureText()

关键代码是将文字贴到图片上

ctx.fillText(obj.text, centerX, centerY)

最后就是将最开始的img标签改变它的src属性,让其显示出来,以及提供下载按钮显示

const watermarkedImage = new Image();
          //将canvas转换为DataURL,以便稍后使用。
          watermarkedImage.src = canvas.toDataURL();
          //将水印图片的src属性设置为canvas转换后的DataURL
          document.getElementById('watermark').src = watermarkedImage.src;
          //将下载按钮的display属性设置为'inline-block',以便在canvas下方显示用于下载图片
          document.getElementById('downloadBtn').href = watermarkedImage.src;
          document.getElementById('downloadBtn').style.display = 'inline-block';
        };
        img.src = event.target.result;
      };
      reader.readAsDataURL(file);

现在就可以上传图片生成水印了

也可以提供下载功能

总结

主要的核心逻辑其实也很简单,就是使用canvas画布将图片贴到画布上,然后设置文字水印的颜色,字体大小等属性,将其贴到canvas画布对应的位置上,最后改变原来的img的src属性进行展示水印图片。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【大数据】CDC 技术:变化数据捕获

CDC 技术&#xff1a;变化数据捕获 1.什么是 CDC &#xff1f;2.批处理 vs CDC3.四种 CDC 的实现方法3.1 表元信息 Table metadata3.2 表求差 Table differences3.3 数据库触发器 Trigger-based CDC3.4 数据库事务日志 Log-based CDC 4.Oracle CDC 详解4.1 Oracle CDC 机制4.1.…

leetcode 52. N 皇后 II

2023.9.10 本题是皇后问题的变式&#xff0c;让求出不同解决方案的数量&#xff0c;和之前做过的 N皇后 基本一样&#xff0c;最终返回ans里棋盘的数量即可。 当复习一下皇后问题了&#xff0c;代码如下&#xff1a; class Solution { private:vector<vector<string&g…

无涯教程-JavaScript - AMORDEGRC函数

描述 AMORDEGRC函数返回每个会计期间的折旧。此功能是为法国会计系统提供的。如果在会计期间的中间购买资产,则会考虑按比Example折旧。 该功能类似于AMORLINC,不同之处在于,根据资产的寿命在计算中使用了折旧系数。 语法 AMORDEGRC (cost, date_purchased, first_period, …

SAP MM学习笔记29 - 供给元(供货源)的Block(拉黑)

前面学习了 供给元 的知识。 可以参考如下的URL SAP MM学习笔记28- 供给元&#xff08;供货源&#xff09;决定_东京老树根的博客-CSDN博客 有时候还有什么业务需求呢&#xff1f;就是比如突发要拉黑某个供应商 或 拉黑某个供应商的某个产品&#xff0c; 那又该如何做呢&…

202331读书笔记|《我笨拙地爱着这个世界(“外卖诗人”王计兵自选集)》——脚在泥泞,心有繁花

202331读书笔记|《我笨拙地爱着这个世界&#xff08;“外卖诗人”王计兵自选集&#xff09;》——脚在泥泞&#xff0c;心有繁花 《我笨拙地爱着这个世界&#xff08;“外卖诗人”王计兵自选集&#xff09;》作者王计兵。这是读的他的第二本书&#xff0c;比较有烟火气&#xf…

Spring Messaging远程命令执行漏洞复现(CVE-2018-1270)

一、漏洞说明 Spring Messaging为Spring框架提供消息支持&#xff0c;用户使用受影响版本的Spring Framework时&#xff0c;允许应用程序通过Spring Messaging模块内存中STOMP代理创建WebSocket。由于selector用SpEL表达式编写&#xff0c;并使用StandardEvaluationContext解析…

springBoot对接Apache POI 实现excel下载和上传

搭建springboot项目 此处可以参考 搭建最简单的SpringBoot项目_Steven-Russell的博客-CSDN博客 配置Apache POI 依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.2</version> </…

Flink JobManager的高可用配置

背景 在flink执行中&#xff0c;jobManager是一个负责执行流式应用执行和检查点生成的组件&#xff0c;一旦发生故障&#xff0c;那么其负责的所有应用都会被取消&#xff0c;所以我们需要对JobManager配置高可用的模式 JobManager高可用配置 配置JobManager的高可用需要使用…

微信小程序云开发数据懒加载+打破云数据库返回数据条数限制

目录 数据懒加载 打破数据表返回条数限制 数据懒加载 show.wxml <view wx:for="{{Adata}}" wx:key="index" style="padding: 80rpx 10rpx 140rpx;border-bottom: rgb(109, 134, 134) 2px solid;"><view style="margin-left: 20…

Notpad++常用正则表达式替换案例集锦

1、在每行的开头加上单引号 2、在每行的结尾加上单引号 3、“删除”某个关键字之前字符串 原始字符串&#xff1a; 注&#xff1a;仅保留含有"[条件日志]:"之后的内容&#xff0c;“日志:”前面的内容“删除”掉&#xff0c;即替换为“”。 4、“删除”某个关键字…

Discourse 可以支持的存储类型

根据官方的这个主题&#xff1a;Configure an S3 compatible object storage provider for uploads - sysadmin - Discourse Meta Discourse 可以支持很多不同的对象存储。 感觉上是只要和 S3 兼容的基本上都能用。 建议 从对象存储的角度考虑&#xff0c;还是建议使用 S3。…

UG\NX CAM二次开发 设置工序检查体 UF_CAMGEOM_append_items

文章作者:代工 来源网站:NX CAM二次开发专栏 简介: UG\NX CAM二次开发 设置工序检查体 UF_CAMGEOM_append_items 效果: 代码: static int init_proc(UF_UI_selection_p_t select, void* user_data) { int errorCode = 0; int num_triples = 1;//UF_UI_mask_t…

Python学习笔记:导入txt、xlsx文件并做简单函数处理

1.txt文件 1.1路径 file_path "E:\Python Project\temp.txt" with open(file_path) as f:content1 f.read() 导入文件时&#xff0c;如果直接放文件绝对路径上去会报错&#xff0c;这是因为\P是转义字符 所以在绝对路径前面加r可以避免将引号内的内容识别成转义…

视觉识别数字、十字路口和T字路口,巡线于一体的基于openmv的解决方案(2021年电赛f题)

普通二本生&#xff08;大二&#xff09;没获奖&#xff0c;因为驱动方面和视觉协同问题没有做好(驱动方面跑太快&#xff0c;速度降不下来)只跑了最初级的&#xff0c;这个文章就是去记录一下我的成长过程吧。 目录 1.使用神经网络来进行识别2.使用模板匹配来进行识别1.1 将这…

Idea上传gitee注意事项,push reject错误

一、 你在项目所在文件夹的空白处&#xff0c;鼠标右键&#xff0c;点击git bash here 会自动进入该目录下 二、 如果你遇到push reject 输入下面的命令&#xff1a; git pull origin master –allow-unrelated-historiesgit push -u origin master -f再次push就好了。 三、 …

教你怎么爬元气桌面的壁纸和视频

开发语言&#xff1a;我大前端必备的nodejs 看成果先&#xff1a; 这次爬下来的是手机端视频壁纸&#xff0c;共848个视频 -----------------------------------下边正式开始---------------------------------- 1、用fiddler抓包&#xff0c;查看接口地址 接口地址为&#…

springboot~自定义favicon加载问题

影响自定义favicon加载的原因 1、浏览器缓存问题2、由于favicon图标是在一个session会话中&#xff0c;所以需要关闭重开浏览器3、favicon源文件格式问题 1、浏览器缓存问题 清空浏览器缓存&#xff0c;或者是在network请求中停用缓存 2、由于favicon图标是在一个session会话中…

18 矩阵置0

矩阵置0 题解1 首行首列做标志记录&#xff08;原地改数组&#xff09;题解2 位计算 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 提示&#xff1a; m matrix.lengthn matrix[0].length1 …

210. 课程表 II

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;拓扑排序 写在最后 Tag 【拓扑排序】 题目来源 210. 课程表 II 题目解读 在选修某些课程之前需要先学习某些课程&#xff0c;先学习的课程有数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [ai, bi] 表…

机器学习入门教学——交叉验证

1、简介 交叉验证是在机器学习建立模型和验证模型参数时常用的办法&#xff0c;一般被用于评估一个机器学习模型的表现。更多的情况下&#xff0c;我们也用交叉验证来进行模型选择。【注】在训练模型时&#xff0c;为了提高模型的质量&#xff0c;我们会将数据集划分为训练集、…