(分享)一个图片添加水印的小demo的页面,可自定义样式

有时候想给某张图片添加一个自己的水印,但是又懒的下载相应软件,用js canvas制作一个静态页面,对于单张图片添加自定义文字水印,大小 间距,角度可调。
页面如下:
在这里插入图片描述
选择图片,设置相应参数,点击添加水印:
在这里插入图片描述
效果:
在这里插入图片描述
完整程序如下:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>添加水印</title><link rel="shortcut icon" href="https://img1.imgtp.com/2024/01/09/BKw2wjPL.png" type="image/x-icon"><style>body {background-color: #c8adc4;}.ml-5 {margin-left: 15px;}.container {display: flex;justify-content: space-between;/* 使两个 div 平均分布在容器中 */}.box {width: 49.5%;/* 或根据需要设置 *//* 其他样式 */}#canvas {border: 2px solid rgb(210, 208, 208);width: 95%;height: auto;overflow: hidden;}#p {margin-top: 20px;width: 95%;height: auto;}#canvas img {width: 100%;height: 100%;object-fit: cover;}#imageUpload {height: auto;width: auto;font-size: 16px;}</style>
</head><body><div class="container"><div class="box"><div style="border: 2px solid #c9c9c9cc; padding: 10px;"><div><input type="file" id="imageUpload" style="color: rgb(249, 137, 109); margin-left: 40%;"></div><div style="margin-left: 10%;margin-top: 30px;"><span>大小:</span><input type="text" placeholder="修改水印大小" style="height: 24px;width: 100px;"value="100" id="ipt1"><span class="ml-5">透明度:</span><input type="text" placeholder="范围1~10"style="height: 24px;width: 100px;" value="5" id="ipt2"><span class="ml-5">间距:</span><input type="text" placeholder="范围1-10"style="height: 24px;width: 100px;" value="5" id="ipt3"></div><div style="margin-top: 20px;margin-left: 10%;"><span class="ml-5">倾斜方向:</span><select id="s2"><option value="left">左倾斜</option><option value="right">右倾斜</option></select><span class="ml-5">倾斜角度:</span><input type="text" placeholder="修改倾斜大小" style="height: 20px;width: 30px;" value="30" id="ipt4"><spanstyle="margin-left: 5px; ;"></span></div><div style="margin-left: 10%;margin-top: 40px;">文本:<input type="text" id="watermarkText" placeholder="请输入水印内容" style="height: 24px;"><button id="confirmButton"style="margin-left: 100px; width: 80px;height: 30px;background-color: rgb(127, 214, 255);color: white;font-size: 16px;border: none;border-radius: 5px;">添加水印</button><button id="saveButton"style="width: 60px;height: 30px;background-color: rgb(28, 119, 161);color: white;font-size: 16px;border: none;border-radius: 5px;">下载</button><button id="reflash" onclick="flush()"style="width: 80px;height: 30px;background-color: rgb(248, 126, 81);color: white;font-size: 16px;border: none;border-radius: 5px;">重置页面</button></div></div><span style="color: rgb(255, 255, 255); font-weight: bold;font-size: 20px;">原图:</span><img id="p"></img></div><div class="box"><span style="color: rgb(255, 255, 255); font-weight: bold;font-size: 20px;">预览框:</span><canvas id="canvas"></canvas></div></div><script>//回显document.getElementById('imageUpload').addEventListener('change', function (e) {var reader = new FileReader();reader.onload = function (e) {document.getElementById('p').src = e.target.result;document.getElementById('p').style.display = 'block';}reader.readAsDataURL(e.target.files[0]);})//添加水印document.getElementById('confirmButton').addEventListener('click', function () {var image = document.getElementById('imageUpload').files[0]; //图片对象var watermarkText = document.getElementById('watermarkText').value; //水印对象var canvas = document.getElementById('canvas');  //canvasvar ctx = canvas.getContext('2d');var img = new Image(); //img对象var fontsize = document.getElementById('ipt1').value; //初始大小var transparency = document.getElementById('ipt2').value / 10; //透明度var jianju = document.getElementById('ipt3').value; //间距//单行多行//倾斜方式var tilt = document.getElementById('s2').value;var angle = document.getElementById('ipt4').value;img.onload = function () {canvas.width = img.width;canvas.height = img.height;ctx.drawImage(img, 0, 0, img.width, img.height);ctx.font = fontsize + 'px Arial'; //大小 字体ctx.fillStyle = `rgba(170, 171, 172, ${transparency})`;if (tilt === 'left') painWatermarket_left(watermarkText, canvas, jianju, ctx, angle);if (tilt === 'right') painWatermarket_right(watermarkText, canvas, jianju, ctx, angle);};img.src = URL.createObjectURL(image);});// 单行左倾斜params: watermarkText canvas jianju\ function painWatermarket_left(watermarkText, canvas, jianju, ctx, angle, lineNumber) {var txtLen = Math.ceil(ctx.measureText(watermarkText).width / 2);for (var i = 150 - txtLen, j = 150 - txtLen;i < canvas.width, j < canvas.height;i += canvas.width / jianju, j += canvas.height / jianju) {ctx.save();ctx.translate(i, j);ctx.rotate(angle * Math.PI / 180);ctx.fillText(watermarkText, 0, 0);ctx.restore();}}// 单行右倾斜params: watermarkText canvas jianjufunction painWatermarket_right(watermarkText, canvas, jianju, ctx, angle) {angle = -1 * angle;var txtLen = Math.ceil(ctx.measureText(watermarkText).width / 2); //文本宽度for (var i = 150 - txtLen, j = canvas.height; i < canvas.width, j > 150 - txtLen; i += canvas.width / jianju, j -= canvas.height / jianju) {ctx.save();ctx.translate(i, j);ctx.rotate(angle * Math.PI / 180);ctx.fillText(watermarkText, 0, 0);ctx.restore();}}//保存document.getElementById('saveButton').addEventListener('click', function () {var canvas = document.getElementById('canvas');var dataUrl = canvas.toDataURL('image/png');var blob = dataURItoBlob(dataUrl);var link = document.createElement('a');link.href = window.URL.createObjectURL(blob);link.download = 'demo.png';link.click();});function dataURItoBlob(dataURI) {var byteString;if (dataURI.split(',')[0].indexOf('base64') >= 0)byteString = atob(dataURI.split(',')[1]);elsebyteString = unescape(dataURI.split(',')[1]);var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];var ab = new ArrayBuffer(byteString.length);var ia = new Uint8Array(ab);for (var i = 0; i < byteString.length; i++) {ia[i] = byteString.charCodeAt(i);}return new Blob([ab], { type: mimeString });}//重置function flush() {location.reload();}</script>
</body></html>

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KVM:尝试安装windows2008

最终目的是在lxd部署windows2008镜像 WindowsServer2008镜像&#xff1a; cn_windows_server_2008_r2_standard_enterprise_datacenter_and_web_with_sp1_x64_dvd_617598.iso 镜像参考链接&#xff1a; https://discussion.scottibyte.com/t/migrate-a-hyper-v-windows-vir…

44 el-dialog 的 appendToBody 属性, 导致 vue 响应式失效

前言 我们经常会碰到 一些 模型和视图 不同步的问题 通常意义上 主要的问题为 列表的某响应式数据更新着更新着 后面就变成非响应式对象了, 然后 就造成了 数据一直在更新, 但是 视图的渲染后面就未渲染了, 这是一个由于 模型上的问题 导致的数据的不在响应式更新 又或者 是…

.NET CORE 分布式事务(三) DTM实现Saga及高并发下的解决方案

目录(结尾附加项目代码资源地址) 引言&#xff1a; 1. SAGA事务模式 2. 拆分为子事务 3. 失败回滚 4. 如何做补偿 4.1 失败的分支是否需要补偿 5. 异常 6. 异常与子事务屏障 6.1 NPC的挑战 6.2 现有方案的问题 6.3 子事务屏障 6.4 原理 7. 更多高级场景 7.1 部分…

MySQL Explain 字段详解

Explain 工具介绍 Explain 一般被称为解释器&#xff0c;通过 Explain 工具&#xff0c;我们能分析我们使用的查询语句或是结构的性能瓶颈&#xff0c;它提供 MySQL 如何执行语句的信息。 使用语法&#xff1a; explain [extended|partition] select在 select 关键字前加 ex…

【大数据】Flink学习笔记

文章目录 认识FlinkDocker安装Flink基本概念Flink的特点Flink 和 Spark Streaming 对比 基本使用WordCount实现依赖 批模式代码流模式代码网络流模式代码在web UI上提交代码创建项目[^1]编写代码配置打包在Web UI上提交 Flink 架构系统架构核心概念并行度算子链(Opeartor Chain…

基于java+springboot+vue实现的电商个性化推荐系统(文末源码+Lw+ppt)23-389

摘 要 伴随着我国社会的发展&#xff0c;人民生活质量日益提高。于是对电商个性化推荐进行规范而严格是十分有必要的&#xff0c;所以许许多多的信息管理系统应运而生。此时单靠人力应对这些事务就显得有些力不从心了。所以本论文将设计一套电商个性化推荐系统&#xff0c;帮…

bert 适合 embedding 的模型

目录 背景 embedding 求最相似的 topk 结果查看 背景 想要求两个文本的相似度&#xff0c;就单纯相似度&#xff0c;不要语义相似度&#xff0c;直接使用 bert 先 embedding 然后找出相似的文本&#xff0c;效果都不太好&#xff0c;试过 bert-base-chinese&#xff0c;be…

pdf在浏览器上无法正常加载的问题

一、背景 觉得很有意思给大家分享一下。事情是这样的&#xff0c;开发给我反馈说&#xff0c;线上环境接口请求展示pdf异常&#xff0c;此时碰巧我前不久正好在ingress前加了一层nginx&#xff0c;恰逢此时内心五谷杂陈&#xff0c;思路第一时间便放在了改动项。捣鼓了好久无果…

vue中使用图片url直接下载图片

vue中使用图片url直接下载图片 // 下载图片downloadByBlob(url, name) {let image new Image()image.setAttribute(crossOrigin, anonymous)image.src urlimage.onload () > {let canvas document.createElement(canvas)canvas.width image.widthcanvas.height image…

Ubuntu20.04下PCL安装,查看,卸载等操作

Ubuntu20.04下PCL安装&#xff0c;查看&#xff0c;卸载等操作 项目来源 https://github.com/PointCloudLibrary/pclhttps://pointclouds.org/documentation/modules.htmlhttps://pcl.readthedocs.io/projects/tutorials/en/master/ 点云学习&#xff1a; https://github.c…

【Spring】SpringMvc项目当中,页面删除最后一条数据,页面不跳转并且数据为空。

期待您的关注 在之前学习SpringMvc的时候遇到过这样一个BUG&#xff0c;当我在一个页面删除该页面的最后一条数据的时候&#xff0c;一旦我删除成功&#xff0c;那么这个页面不会进行跳转&#xff0c;而是还停留在这个本不应该存在的页面&#xff0c;而且数据什么都没有。如下…

零基础教程:R语言lavaan结构方程模型(SEM)

查看原文>>>最新基于R语言lavaan结构方程模型&#xff08;SEM&#xff09;实践技术应用 基于R语言lavaan程序包&#xff0c;通过理论讲解和实际操作相结合的方式&#xff0c;由浅入深地系统介绍结构方程模型的建立、拟合、评估、筛选和结果展示的全过程。我们筛选大量…

ChatGPT与Discord的完美结合——团队协作的得力助手

本文将教你如何集成Discord Bot&#xff0c;助力团队在工作中实现更高效的沟通与协作。通过充分发挥ChatGPT的潜力&#xff0c;进一步提升工作效率和团队协作能力。无需编写任何代码即可完成本文所述的操作&#xff0c;进行个性化定制只需对参数进行微调即可。 方案介绍 如果在…

【JavaWeb】Day27.Web入门——Tomcat介绍

目录 WEB服务器-Tomcat 一.服务器概述 二.Web服务器 三.Tomcat- 基本使用 1.下载 2.安装与卸载 3.启动与关闭 4.常见问题 四.Tomcat- 入门程序 WEB服务器-Tomcat 一.服务器概述 服务器硬件&#xff1a;指的也是计算机&#xff0c;只不过服务器要比我们日常使用的计算…

AI绘画核心技术与实战【课程推荐】

AI结合绘画领域属于是《黑客与画家》的结合了&#xff0c;推荐大家来一起学习

Linux:程序地址空间详解

目录 一、堆、栈、环境参数所在位置 二、进程地址空间底层实现原理 ​编辑 三、什么是地址空间 四、为什么要有进程地址空间 五、细谈写实拷贝的实现及意义 在C/C学习中&#xff0c;都学习过如上图所示的一套存储结构&#xff0c;我们大致知道一般存储空间分为堆区&#…

代码随想录算法训练营三刷 day38 | 动态规划之 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

三刷day38 509. 斐波那契数1 确定dp数组以及下标的含义2 确定递推公式3 dp数组如何初始化4 确定遍历顺序5 举例推导dp数组 70. 爬楼梯1 确定dp数组以及下标的含义2 确定递推公式3 dp数组如何初始化4 确定遍历顺序5 举例推导dp数组 746. 使用最小花费爬楼梯1 确定dp数组以及下标…

[C++初阶] 爱上C++ : 与C++的第一次约会

&#x1f525;个人主页&#xff1a;guoguoqiang &#x1f525;专栏&#xff1a;我与C的爱恋 本篇内容带大家浅浅的了解一下C中的命名空间。 在c中&#xff0c;名称&#xff08;name&#xff09;可以是符号常量、变量、函数、结构、枚举、类和对象等等。工程越大&#xff0c;名称…

C++进阶,手把手带你学继承

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;c大冒险 总有光环在陨落&#xff0c;总有新星在闪烁 【本节目标】 1.继…

【讲解下go和java的区别】

&#x1f525;博主&#xff1a;程序员不想YY啊&#x1f525; &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家&#x1f4ab; &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 &#x1f308;希望本文对您有所裨益&#xff0c;如有…