我们将使用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();