HTML实现图片上添加水印的工具

HTML实现图片上添加水印的工具

本文介绍两种实现方式:图片上添加文字水印和图片上添加图片水印。部分源码参照自网络。

一、图片上添加文字水印

先看效果图:

源码如下:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片水印工具</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            margin: 20px;
            background-color: #f0f0f0;
        }
        h1 {
            color: #333;
        }
        .container {
            background-color: white;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        input[type="file"], input[type="text"], select, input[type="number"], input[type="range"], input[type="color"] {
            margin: 10px 0;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            width: 300px;
        }
        button {
            margin: 10px;
            padding: 10px 20px;
            background-color: #007BFF;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        button:hover {
            background-color: #0056b3;
        }
        #canvas {
            margin-top: 20px;
            border: 1px solid #ccc;
            box-shadow: 0 0 5px rgba(0,0,0,0.2);
            display: none; /* 初始隐藏 canvas */
        }
        .options {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-around;
            width: 100%;
        }
        .option-group {
            margin: 10px;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>图片文字水印工具</h1>
        <input type="file" id="upload" accept="image/*">
        <input type="text" id="watermark-text" placeholder="输入水印文字">
        <div class="options">
            <div class="option-group">
                <label for="font-size">文字大小:</label>
                <select id="font-size">
                    <option value="12">12px</option>
                    <option value="16">16px</option>
                    <option value="20" selected>20px</option>
                    <option value="24">24px</option>
                </select>
            </div>
            <div class="option-group">
                <label for="rotation">旋转角度(度):</label>
                <input type="number" id="rotation" value="-45" step="1">
            </div>
            <div class="option-group">
                <label for="font-family">字体:</label>
                <select id="font-family">
                    <option value="Arial" selected>Arial</option>
                    <option value="Times New Roman">Times New Roman</option>
                    <option value="Courier New">Courier New</option>
                    <option value="Verdana">Verdana</option>
                </select>
            </div>
            <div class="option-group">
                <label for="opacity">透明度(0-100):</label>
                <input type="range" id="opacity" min="0" max="100" value="50">
            </div>
            <div class="option-group">
                <label for="horizontal-spacing">水平间距(像素):</label>
                <input type="number" id="horizontal-spacing" value="50" min="10" step="10">
            </div>
            <div class="option-group">
                <label for="vertical-spacing">行间距(像素):</label>
                <input type="number" id="vertical-spacing" value="100" min="10" step="10">
            </div>
            <div class="option-group">
                <label for="font-color">字体颜色选择:</label>
                <input type="color" id="font-color" value="#FFFFFF">
            </div>
        </div>
        <button id="add-watermark">添加水印</button>
        <canvas id="canvas"></canvas>
        <button id="download" style="display: none;">下载图片</button>
    </div>

    <script>
        let originalImage = null;
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');

        // 上传图片
        document.getElementById('upload').addEventListener('change', function(e) {
            const file = e.target.files[0];
            if (!file) return;

            const reader = new FileReader();
            reader.onload = function(event) {
                const img = new Image();
                img.onload = function() {
                    originalImage = img;
                    // 动态设置 canvas 尺寸为原图尺寸
                    canvas.width = img.width;
                    canvas.height = img.height;
                    // 绘制原图
                    ctx.clearRect(0, 0, canvas.width, canvas.height);
                    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
                    document.getElementById('download').style.display = 'none';
                    // 显示 canvas
                    canvas.style.display = 'block';
                };
                img.src = event.target.result;
            };
            reader.readAsDataURL(file);
        });

        // 添加水印
        document.getElementById('add-watermark').addEventListener('click', function() {
            if (!originalImage) {
                alert('请先上传图片');
                return;
            }
            const text = document.getElementById('watermark-text').value;
            if (!text) {
                alert('请输入水印文字');
                return;
            }
            const fontSize = document.getElementById('font-size').value;
            const rotation = parseFloat(document.getElementById('rotation').value);
            const fontFamily = document.getElementById('font-family').value;
            const opacity = parseInt(document.getElementById('opacity').value) / 100;
            const horizontalSpacing = parseInt(document.getElementById('horizontal-spacing').value);
            const verticalSpacing = parseInt(document.getElementById('vertical-spacing').value);
            const fontColor = document.getElementById('font-color').value;

            // 清除 canvas 并重新绘制原图
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.drawImage(originalImage, 0, 0, canvas.width, canvas.height);

            // 设置水印样式
            ctx.font = `${fontSize}px ${fontFamily}`;
            ctx.fillStyle = `rgba(${parseInt(fontColor.slice(1, 3), 16)}, ${parseInt(fontColor.slice(3, 5), 16)}, ${parseInt(fontColor.slice(5, 7), 16)}, ${opacity})`;
            ctx.textBaseline = 'middle';
            ctx.save();
            // 移动到 canvas 中心并旋转
            ctx.translate(canvas.width / 2, canvas.height / 2);
            const angle = rotation * Math.PI / 180;
            ctx.rotate(angle);
            // 计算水印布局
            const textWidth = ctx.measureText(text).width;
            const diagonal = Math.sqrt(canvas.width * canvas.width + canvas.height * canvas.height);
            const cols = Math.ceil(diagonal / (textWidth + horizontalSpacing));
            const rows = Math.ceil(diagonal / verticalSpacing);
            // 绘制水印
            for (let i = -rows; i < rows; i++) {
                for (let j = -cols; j < cols; j++) {
                    const x = j * (textWidth + horizontalSpacing);
                    const y = i * verticalSpacing;
                    ctx.fillText(text, x, y);
                }
            }
            ctx.restore();
            document.getElementById('download').style.display = 'inline-block';
        });

        // 下载图片
        document.getElementById('download').addEventListener('click', function() {
            const dataURL = canvas.toDataURL('image/png');
            const a = document.createElement('a');
            a.href = dataURL;
            a.download = 'watermarked-image.png';
            a.click();
        });
    </script>
</body>
</html>

二、图片上添加图片水印

先看效果图:

源码如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片水印工具</title>
    <style>
        .container { 
            width: 500px; 
            margin: 20px auto; 
            padding: 20px; 
            border: 1px solid #ccc; 
            border-radius: 8px; 
        }

        canvas { 
            max-width: 100%; 
            margin-top: 15px; 
            border: 1px solid #ddd; 
        }


        h1 {
            font-size: 20px;
            text-align: center;
            margin-bottom: 20px;
        }

        .section {
            margin-bottom: 15px;
        }

        input[type="file"] {
            margin: 5px 0;
        }

        .buttons {
            display: flex;
            gap: 10px;
            margin: 10px 0;
        }

        button {
            padding: 8px 15px;
            cursor: pointer;
            background-color: #f0f0f0;
            border: 1px solid #ccc;
            border-radius: 4px;
        }

        #download {
            display: block;
            width: 100%;
            padding: 10px;
            background-color: #4CAF50;
            color: white;
            border: none;
            margin-top: 15px;
        }

        .coord {
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>图片添加图片水印工具</h1>
        
        <div class="section">
            <label>选择背景图片:</label>
            <input type="file" id="bgImage" accept="image/*">
            <span id="bgFileName"></span>
        </div>

        <div class="section">
            <label>上传图片水印:</label>
            <input type="file" id="watermark" accept="image/*">
            <span id="wmFileName"></span>
        </div>

        <div class="section">
            <label>水印缩放比例:</label>
            <input type="range" id="scale" min="10" max="100" value="50">
            <span id="scaleValue">50%</span>
        </div>

        <div class="section">
            <label>水印透明度:</label>
            <input type="range" id="opacity" min="0" max="100" value="100">
            <span id="opacityValue">100%</span>
        </div>

        <div class="section">
            <h3>水印位置调整</h3>
            <div class="buttons">
                <button type="button" onclick="adjustY(-20)">上移</button>
                <button type="button" onclick="adjustY(20)">下移</button>
                <button type="button" onclick="adjustX(-20)">左移</button>
                <button type="button" onclick="adjustX(20)">右移</button>
            </div>
            <div class="coord">
                X 坐标:<span id="xCoord">90</span>
                Y 坐标:<span id="yCoord">50</span>
            </div>
        </div>

        <button type="button" id="download">下载生成图片</button>
        
        <canvas id="previewCanvas"></canvas> 
    </div>

    <script>
        const canvas = document.getElementById('previewCanvas');
        const ctx = canvas.getContext('2d');
        let bgImage, watermarkImage;
        
        // 文件加载处理
        document.getElementById('bgImage').addEventListener('change', function(e) {
            loadImage(e.target.files[0]).then(img => {
                bgImage = img;
                updateCanvasSize();
                drawImages();
            });
        });

        document.getElementById('watermark').addEventListener('change', function(e) {
            loadImage(e.target.files[0]).then(img => {
                watermarkImage = img;
                drawImages();
            });
        });

        // 图像加载函数
        function loadImage(file) {
            return new Promise((resolve, reject) => {
                const reader = new FileReader();
                reader.onload = (e) => {
                    const img = new Image();
                    img.onload = () => resolve(img);
                    img.src = e.target.result;
                };
                reader.readAsDataURL(file);
            });
        }

        // 更新Canvas尺寸匹配背景图
        function updateCanvasSize() {
            if (!bgImage) return;
            canvas.width = bgImage.width;
            canvas.height = bgImage.height;
        }

        // 核心绘制函数
        function drawImages() {
            if (!bgImage || !watermarkImage) return;
            
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // 绘制背景图
            ctx.drawImage(bgImage, 0, 0);
            
            // 计算水印参数
            const scale = document.getElementById('scale').value / 100;
            const opacity = document.getElementById('opacity').value / 100;
            const x = parseInt(document.getElementById('xCoord').textContent);
            const y = parseInt(document.getElementById('yCoord').textContent);
            
            // 绘制水印
            ctx.save();
            ctx.globalAlpha = opacity;
            ctx.drawImage(
                watermarkImage,
                x, y,
                watermarkImage.width * scale,
                watermarkImage.height * scale
            );
            ctx.restore();
        }

        // 滑块和按钮事件绑定
        document.getElementById('scale').addEventListener('input', function(e) {
            document.getElementById('scaleValue').textContent = e.target.value + '%';
            drawImages();
        });
    
        document.getElementById('opacity').addEventListener('input', function(e) {
            document.getElementById('opacityValue').textContent = e.target.value + '%';
            drawImages();
        });

        // 坐标调整函数(修改后)
        function adjustX(delta) {
            const x = parseInt(document.getElementById('xCoord').textContent) + delta;
            document.getElementById('xCoord').textContent = x;
            drawImages();
        }

        function adjustY(delta) {
            const y = parseInt(document.getElementById('yCoord').textContent) + delta;
            document.getElementById('yCoord').textContent = y;
            drawImages();
        }

        // 下载功能
        document.getElementById('download').addEventListener('click', () => {
            if (!bgImage || !watermarkImage) {
                alert('请先选择背景图和水印图');
                return;
            }
            
            const link = document.createElement('a');
            link.download = 'watermarked-image.png';
            link.href = canvas.toDataURL('image/png');
            link.click();
        });
    </script>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习&实践爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值