当前位置: 首页 > news >正文

(分享)一个图片添加水印的小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>

相关文章:

  • 03---java面试八股文——spring-----注解-------10题
  • sqlite删除数据表
  • web学习笔记(四十五)Node.js
  • 第一次运行 Python 项目,使用 python-pptx 提取 ppt 中的文字和图片
  • 前端理论总结(css3)——页面布局方法
  • 野心、梦想与科幻——浅谈外星殖民与软件工程
  • canal: 连接kafka (docker)
  • 北京小蓝蜂科技有限公司 基本情况
  • SAP Fiori开发中的JavaScript基础知识9 - 代码注释,严格模式,JSON
  • Adobe Illustrator 2023 for Mac/Win:创意无限,设计无界
  • 【Qt】:坐标
  • 使用Docker Compose一键部署前后端分离项目(图文保姆级教程)
  • 基于Spring Boot的在线学习系统的设计与实现
  • 虚幻引擎资源加密方案解析
  • vue3+threejs新手从零开发卡牌游戏(十四):调整卡组位置,添加玩家生命值HP和法力值Mana信息
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • 2019年如何成为全栈工程师?
  • Apache Spark Streaming 使用实例
  • AWS实战 - 利用IAM对S3做访问控制
  • C学习-枚举(九)
  • Druid 在有赞的实践
  • FastReport在线报表设计器工作原理
  • Github访问慢解决办法
  • go语言学习初探(一)
  • iOS小技巧之UIImagePickerController实现头像选择
  • nodejs调试方法
  • Python进阶细节
  • Vue学习第二天
  • vue学习系列(二)vue-cli
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 排序(1):冒泡排序
  • 深入浏览器事件循环的本质
  • 详解移动APP与web APP的区别
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • 译有关态射的一切
  • - 转 Ext2.0 form使用实例
  • 自定义函数
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • # Panda3d 碰撞检测系统介绍
  • #13 yum、编译安装与sed命令的使用
  • #Linux(make工具和makefile文件以及makefile语法)
  • $L^p$ 调和函数恒为零
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (区间dp) (经典例题) 石子合并
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • (转)ABI是什么
  • ***检测工具之RKHunter AIDE