js图片增加水印,并上传服务器

一、前端代码

  1. watermark.js 工具类
/**
 * 添加水印 异步
 * @param {图片file,在inout中的file} file
 * @param {水印数组,比如名字,电话,时间,地址} watermarks
 */
function addWatermarkAndUpload(file, watermarks) {
    return new Promise(((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = function (event) {
            const img = new Image();
            img.onload = function () {
                const canvas = document.createElement('canvas');
                const ctx = canvas.getContext('2d');

                // 设置canvas尺寸与图片一致
                canvas.width = img.width;
                canvas.height = img.height;

                // 绘制图片到canvas
                ctx.drawImage(img, 0, 0, img.width, img.height);

                //水印大小和颜色
                let fontSize = 100
                ctx.font = fontSize + 'px Arial';
                ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
                //水印起始位置,默认左下角
                let x = 20
                let y = 20
                // 添加水印
                for (let i = 0; i < watermarks.length; i++) {
                    y = watermarkHandle(ctx, watermarks[i], canvas.width, canvas.height, fontSize, x, y)
                }
                // 将带有水印的canvas转换为Blob对象
                canvas.toBlob((blob) => {
                    if (blob) {
                        blob.name = file.name
                        resolve(blob);
                    } else {
                        reject(new Error('Failed to create blob from canvas'));
                    }
                }, 'image/png');
            };
            img.src = event.target.result;
        };
        reader.readAsDataURL(file);
    }));
}

/**
 * 写入水印,默认左下角 水印过长,换行 (x,y)=(0,0) 就是左下角的位置
 *  @param {canvas画布对象} ctx
 *  @param {单个水印} watermark
 *  @param {图片的长宽} height
 *  @param {图片的长宽} width
 *  @param {水印字体大小} fontSize
 *  @param {水印位置,默认左下角} x
 *  @param {水印位置,默认左下角} y
 */
function watermarkHandle(ctx, watermark, width, height, fontSize, x, y) {
    //添加水印
    let lineHeight = fontSize + 10
    let line = '';
    const list = [];
    for (let i = 0; i < watermark.length; i++) {
        const testLine = line + watermark[i];
        const metrics = ctx.measureText(testLine);
        const testWidth = metrics.width;
        if (testWidth < width - fontSize && i < watermark.length - 1) {
            line = testLine;
        } else {
            list.push(line)
            line = watermark[i];
        }
    }
    const testLine = line + list[list.length - 1];
    const metrics = ctx.measureText(testLine);
    const testWidth = metrics.width;
    if (testWidth < width - fontSize) {
        list[list.length - 1] = list[list.length - 1] + line
    } else {
        list.push(line)
    }
    for (let i = list.length - 1; i >= 0; i--) {
        ctx.fillText(list[i], x, height - y);
        y += lineHeight;
    }
    //位置
    return y;
}

  1. 使用
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片水印并上传示例</title>
</head>
<body>
<input type="file" id="imageFile" accept="image/*">
<button onclick="addWatermark()">添加水印并上传</button>

<script th:src="@{/js/watermark.js}"></script>
<script>
    function addWatermark() {
        const imageFileInput = document.getElementById('imageFile');
        const file = imageFileInput.files[0];

        if (!file) {
            alert('请先选择图片!');
            return;
        }
        var watermarks = []
        watermarks.push("广西壮族自2心2圩街2汇11111111111111111111111112")
        watermarks.push("2024-05-11 19:13:04 ")
        watermarks.push("李华 130733376")
        const promises = [];
        for (let i = 0; i < 3; i++) {
            promises.push(addWatermarkAndUpload(file, watermarks))
        }
        Promise.all(promises)
            .then(results => {
                // 当所有Promise都完成时,results数组包含所有结果
                console.log(results);
                // 在这里你可以一起处理所有结果
                const formData = new FormData();
                for (let i = 0; i < results.length; i++) {
                    console.log(results[i])
                    formData.append('files', results[i], results[i].name);
                }
                return formData;
            })
            .then(formData => {
                //上传,注意上传接口多个文件
               return  fetch('/common/uploads', {
                    method: 'POST',
                    body: formData
                });
            })
            .then(response => {
                // 处理响应
                return response.json();
            })
            .then(data => {
                // 处理返回的数据,url
                console.log(data);
                //其他操作操作
            })
            .catch(error => {
                // 处理错误
                console.error('Error:', error);
            })
    }
</script>
</body>
</html>

二、完整前后端代码

全部代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值