(分享)一个图片添加水印的小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.mzph.cn/news/772345.shtml

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

相关文章

公众号超牛鼻的爆文仿写机器人,原创三篇只需6分钟,篇篇是爆文基因

大家好&#xff0c;我是大胡子&#xff0c;专注于RPA提效​&#xff0c;今天就介绍一款公众号超牛鼻的爆文仿写机器人​。 和以前的公众号爆文机器人不太一样&#xff0c;以前的爆文机器人需要手动插入图片、添加封面、插入话题&#xff0c;然后今天这个机器人就完全解决这几个…

代码随想录算法训练营第五十五天|583. 两个字符串的删除操作、72. 编辑距离

583. 两个字符串的删除操作 刷题https://leetcode.cn/problems/delete-operation-for-two-strings/description/文章讲解https://programmercarl.com/0583.%E4%B8%A4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%88%A0%E9%99%A4%E6%93%8D%E4%BD%9C.html视频讲解https://…

详解:写作和赚钱的 4 个关系!看完你一定会忍不住想开始写!

飞书文档的加密很强&#xff0c;也没有和自家的豆包大模型融合&#xff0c;所以只能通过其他方式获取文档的内容。 &#xff08;1&#xff09;将飞书文档转换为PDF&#xff0c;要用到浏览器插件&#xff1a; GoFullPage - Full Page Screen Capture - Microsoft Edge Addons …

RT-Thread动态内存扩展,使用多块不连续的RAM作为动态内存

开发环境 MCU&#xff1a;STM32F429VET6&#xff08;1M Flash&#xff0c;192K64K共256K SRAM&#xff09; 编译环境&#xff1a;MDK5.38 实时系统&#xff1a;RT-Thread标准版 目的 这颗MCU的SRAM默认是使用192K&#xff0c;即从地址0x20000000开始&#xff0c;最大0x30000…

第九届蓝桥杯大赛个人赛省赛(软件类)真题C 语言 A 组-分数

solution1 直观上的分数处理 #include <iostream> using namespace std; int main() {printf("1048575/524288");return 0; }#include<stdio.h> #include<math.h> typedef long long ll; struct fraction{ll up, down; }; ll gcd(ll a, ll b){if…

2024中国闪存市场观察:AI助推闪存全面起势?

过去两年&#xff0c;闪存市场一直处于低迷状态&#xff0c;但去年第四季度闪存颗粒资源的上涨&#xff0c;导致闪存产品价格一路上扬&#xff0c;市场遂发生反转。 2024年&#xff0c;中国闪存市场会彻底走向复苏&#xff0c;还是急转直下&#xff1f;中国AI热潮&#xff0c;…

MATLAB 自定义生成平面点云(可指定方向,添加噪声)(48)

MATLAB 自定义生成平面点云(可指定方向,添加噪声)(48) 一、算法介绍二、算法步骤三、算法实现1.代码2.效果一、算法介绍 通过这里的平面生成方法,可以生成模拟平面的点云数据,并可以人为设置平面方向,平面大小,并添加噪声来探索不同类型的平面数据。这种方法可以用于…

数据结构进阶篇 之 【二叉树】详细概念讲解(带你认识何为二叉树及其性质)

有朋自远方来&#xff0c;必先苦其心志&#xff0c;劳其筋骨&#xff0c;饿其体肤&#xff0c;空乏其身&#xff0c;鞭数十&#xff0c;驱之别院 一、二叉树 1、二叉树的概念 1.1 二叉树中组分构成名词概念 1.2 二叉树的结构概念 1.3 特殊的二叉树 2、二叉树的存储结构 …

全面:vue.config.js 的完整配置

vue.config.js是Vue项目的配置文件&#xff0c;用于配置项目的构建、打包和开发环境等。 在Vue CLI 3.0之后&#xff0c;项目的配置文件从原来的build和config目录下的多个配置文件&#xff0c;合并成了一个vue.config.js文件。这个文件可以放在项目的根目录下&#xff0c;用于…

AI入侵游戏业:是颠覆者还是创新助手?揭秘未来游戏新趋势!

在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;已经成为各行各业的关注焦点。而在娱乐产业中&#xff0c;AI技术的引入也让人们对电子游戏的未来发展产生了无限遐想。那么&#xff0c;AI究竟会给电子游戏行业带来怎样的变革&#xff1f;它会成为行业的颠…

通讯录管理系统实现(C++版本)

1.菜单栏的设置 &#xff08;1&#xff09;我么自定义了一个showmenu函数&#xff0c;用来打印输出我们的菜单栏&#xff1b; &#xff08;2&#xff09;菜单栏里面设置一些我们的通讯录里面需要用到的功能&#xff0c;例如增加联系人&#xff0c;删除联系人等等 2.退出功能…

javaWeb私人牙科诊所管理系统

一、摘要 随着科技的飞速发展&#xff0c;计算机已经广泛的应用于各个领域之中。在医学领域中&#xff0c;计算机主要应用于两个方面&#xff1a;一是医疗设备智能化&#xff0c;以硬件为主。另一种是病例信息管理系统&#xff08;HIS&#xff09;以软件建设为主&#xff0c;以…

1978-2022年全国31省社会消费品零售总额数据

1978-2022年全国31省社会消费品零售总额数据 1、时间&#xff1a;1978-2022年 2、指标&#xff1a;社会消费品零售总额 3、范围&#xff1a;31省市 4、来源&#xff1a;整理自国家统计J和各省年鉴 5、缺失情况说明&#xff1a;1997-2022年31省市均无缺失&#xff0c; 199…

随机链表的深拷贝

目录 一、何为深拷贝&#xff1f; 二、题目 三、思路 1.拷贝节点插入到原节点后面 2.控制拷贝节点的random 3.脱离原链表 : 尾插的思想 四、代码 五、附加 一、何为深拷贝&#xff1f; 一个引用对象一般来说由两个部分组成&#xff1a;一个具名的Handle&#xff0c;也就…

面试官问我 ,try catch 应该在 for 循环里面还是外面?

首先 &#xff0c; 话说在前头&#xff0c; 没有什么 在里面 好 和在外面好 或者 不好的 一说。 本篇文章内容&#xff1a; 使用场景 性能分析 个人看法 1. 使用场景 为什么要把 使用场景 摆在第一个 &#xff1f; 因为本身try catch 放在 for循环 外面 和里面 &#…

2024年NOC大赛软件创意编程(python初中组初赛)真题

题型和分值&#xff1a;单选题(20题,40分)、判断题(5题,10分)、多选题(5题,20分)、填空题(10题,30分) 一、单选题&#xff08;每题2分&#xff0c;共20题&#xff0c;满分40分&#xff09; 1、下面的程序&#xff0c;会无限循环下去的是&#xff08; &#xff09; A&#x…

【数据结构】双向奔赴的爱恋 --- 双向链表

关注小庄 顿顿解馋๑ᵒᯅᵒ๑ 引言&#xff1a;上回我们讲解了单链表(单向不循环不带头链表)&#xff0c;我们可以发现他是存在一定缺陷的&#xff0c;比如尾删的时候需要遍历一遍链表&#xff0c;这会大大降低我们的性能&#xff0c;再比如对于链表中的一个结点我们是无法直接…

DNS协议 是什么?说说DNS 完整的查询过程?

一、是什么 DNS&#xff08;Domain Names System&#xff09;&#xff0c;域名系统&#xff0c;是互联网一项服务&#xff0c;是进行域名和与之相对应的 IP 地址进行转换的服务器 简单来讲&#xff0c;DNS相当于一个翻译官&#xff0c;负责将域名翻译成ip地址 IP 地址&#…

js实现拖放效果

dataTransfer对象 说明&#xff1a;dataTransfer对象用于从被拖动元素向放置目标传递字符串数据。因为这个对象是 event 的属性&#xff0c;所以在拖放事件的事件处理程序外部无法访问 dataTransfer。在事件处理程序内部&#xff0c;可以使用这个对象的属性和方法实现拖放功能…

【鸿蒙HarmonyOS开发笔记】使用@Preview装饰器预览组件

概述 ArkTS应用/服务支持组件预览&#xff0c;要求compileSdkVersion为8或以上。组件预览支持实时预览&#xff0c;不支持动态图和动态预览。组件预览通过在组件前添加注解Preview实现&#xff0c;在单个源文件中&#xff0c;最多可以使用10个Preview装饰自定义组件。 Preview…