Nodejs实现图片加水印 【使用jimp】

Nodejs实现图片加水印 【使用jimp】

先看效果

我们将使用jimp实现图片加上水印,可以结合路由进行用户上传后处理该图片生成带水印的图片返回个用户
在这里插入图片描述在这里插入图片描述

const path = require("path");
const jimp = require("jimp");

/**
 * 给一张图片加水印
 * @param {string} waterFile - 水印图片的文件路径
 * @param {string} originFile - 原始图片的文件路径
 * @param {string} targetFile - 输出的带水印图片的文件路径
 * @param {number} [proportion=5] - 水印相对于原始图片的比例
 * @param {number} [marginProportion=0.01] - 水印相对于原始图片边距的比例
 * @param {number} [opacity=0.3] - 水印图片的透明度
 */
async function mark(
    waterFile,
    originFile,
    targetFile,
    proportion = 5,
    marginProportion = 0.01,
    opacity = 0.5
) {
    // 并行读取水印图片和原始图片
    const [water, origin] = await Promise.all([
        jimp.read(waterFile),
        jimp.read(originFile),
    ]);

    // 计算水印图片需要缩放的比例
    const curProportion = origin.bitmap.width / water.bitmap.width;
    // 按照比例缩放水印图片
    water.scale(curProportion / proportion);

    // 设置水印图片的透明度
    water.opacity(opacity);

    // 计算水印图片的旋转角度
    water.rotate(-45);

    // 水印平铺
    const watermarkWidth = water.bitmap.width;
    const watermarkHeight = water.bitmap.height;

    for (let y = -watermarkHeight; y < origin.bitmap.height + watermarkHeight; y += watermarkHeight) {
        for (let x = -watermarkWidth; x < origin.bitmap.width + watermarkWidth; x += watermarkWidth) {
            origin.composite(water, x, y, {
                mode: jimp.BLEND_SOURCE_OVER,
                opacitySource: opacity,
            });
        }
    }

    // 将带水印的图片写入到目标文件
    await origin.write(targetFile);
}

// 测试函数,用于演示给图片加水印
async function test() {
    // 定义水印图片、原始图片和目标图片的路径
    const waterPath = path.resolve(__dirname, "./IMG.jpg");
    const originPath = path.resolve(__dirname, "./vuelogo.png");
    const targetPath = path.resolve(__dirname, "./new.jpg");

    // 给图片加水印
    await mark(waterPath, originPath, targetPath);
}

// 调用测试函数
test();

还可以对其进行改造生成不同尺寸的水印图片

const path = require("path");
const jimp = require("jimp");

/**
 * 给一张图片加水印
 * @param {string} waterFile - 水印图片的文件路径
 * @param {string} originFile - 原始图片的文件路径
 * @param {string} targetFile - 输出的带水印图片的文件路径
 * @param {number} [proportion=5] - 水印相对于原始图片的比例
 * @param {number} [marginProportion=0.01] - 水印相对于原始图片边距的比例
 * @param {number} [opacity=0.5] - 水印图片的透明度
 */
async function mark(
    waterFile,
    originFile,
    targetFile,
    proportion = 5,
    marginProportion = 0.01,
    opacity = 0.5
) {
    // 并行读取水印图片和原始图片
    const [water, origin] = await Promise.all([
        jimp.read(waterFile),
        jimp.read(originFile),
    ]);

    // 计算水印图片需要缩放的比例
    const curProportion = origin.bitmap.width / water.bitmap.width;
    // 按照比例缩放水印图片
    water.scale(curProportion / proportion);

    // 设置水印图片的透明度
    water.opacity(opacity);

    // 计算水印图片的旋转角度
    water.rotate(-45);

    // 水印平铺
    const watermarkWidth = water.bitmap.width;
    const watermarkHeight = water.bitmap.height;

    for (let y = -watermarkHeight; y < origin.bitmap.height + watermarkHeight; y += watermarkHeight) {
        for (let x = -watermarkWidth; x < origin.bitmap.width + watermarkWidth; x += watermarkWidth) {
            origin.composite(water, x, y, {
                mode: jimp.BLEND_SOURCE_OVER,
                opacitySource: opacity,
            });
        }
    }

    // 将带水印的图片写入到目标文件
    await origin.write(targetFile);
}

// 测试函数,用于演示给图片加水印
async function test() {
    // 定义水印图片、原始图片和目标图片的路径
    const waterPath = path.resolve(__dirname, "./IMG.jpg");
    const originPath = path.resolve(__dirname, "./vuelogo.png");

    // 生成三种不同尺寸的水印图片
    const targetPathSmall = path.resolve(__dirname, "./new_small.jpg");
    const targetPathMedium = path.resolve(__dirname, "./new_medium.jpg");
    const targetPathLarge = path.resolve(__dirname, "./new_large.jpg");

    // 给图片加小尺寸水印
    await mark(waterPath, originPath, targetPathSmall, 10, 0.01, 0.5);
    // 给图片加中等尺寸水印
    await mark(waterPath, originPath, targetPathMedium, 5, 0.01, 0.5);
    // 给图片加大尺寸水印
    await mark(waterPath, originPath, targetPathLarge, 2.5, 0.01, 0.5);
}

// 调用测试函数
test();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我叫汪枫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值