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

有时候想给某张图片添加一个自己的水印,但是又懒的下载相应软件,用js canvas制作一个静态页面,对于单张图片添加自定义文字水印,大小 间距,角度可调。

页面如下:

选择图片,设置相应参数,点击添加水印:

效果:

完整程序如下:

html 复制代码
<!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"><span
                        style="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');  //canvas
            var 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 jianju
        function 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]);
            else
                byteString = 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>
相关推荐
WeiXiao_Hyy30 分钟前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡1 小时前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone1 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09011 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农1 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king2 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳2 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵3 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星3 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_3 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js