const fs = require('fs'); const path = require('path'); const sharp = require('sharp'); const Text2SVG = require('text-to-svg'); const { getInputDir } = require('../utils/index'); const { cover } = require('../config/index'); //工作目录文件夹路径 const inputDir = getInputDir(); if (!inputDir) { console.log('未执行添加水印功能,工作目录不存在'); return; } //需要拼图的文件夹 const previewDir = `${inputDir}/预览图`; if (!previewDir) { console.log('未执行添加水印功能,预览图目录不存在'); return; } async function nodeGenWatermark({ img, text, filepath }) { /** * @desc 将水印文字转换成 svg,再转换成buffer * @param {string} text 水印文字 * @param {number} fontSize 字体大小 * @param {string} color 字体颜色 * @return {Buffer} */ function text2SVG({ text, fontSize = 24, color = 'rgba(204, 204, 204, 0.2)' }) { const fontPath = path.join(__dirname, '../assets/STHUPO.TTF'); // 加载字体文件 const text2SVG = Text2SVG.loadSync(fontPath); const options = { fontSize, anchor: 'top', // 坐标中的对象锚点 attributes: { fill: color }, // 文字颜色 }; const textSVG = text2SVG.getSVG(text, options); return Buffer.from(textSVG); } /** * @desc 水印图片旋转45度倾斜 * @param {string} text 水印文字 * @return {Promise} */ async function rotateWatermarkBuffer(text) { // ` ${text} ` 增加下文字间距 const textBuffer = text2SVG({ text: ` ${text} ` }); return sharp(textBuffer) .rotate(330, { background: { r: 255, g: 255, b: 255, alpha: 0 } }) // 旋转330度,并且透明色 .toBuffer(); } /** * @desc 入口文件 * @param {string|Buffer} img 图片本地路径或图片 Buffer 数据 * @param {string} text 水印文字 * @param {string} filepath 保存合成水印后的文件路径 * @return {Promise} */ async function init({ img, text, filepath }) { const textBuffer = await rotateWatermarkBuffer(text); const imgInfo = await sharp(img) // 重复(tile)合并图像 .composite([{ input: textBuffer, tile: true }]) .toFile(filepath); return imgInfo; } await init({ img, text, filepath }); } fs.readdirSync(previewDir).forEach((file) => { const ext = file.split('.').pop().toLowerCase(); if (cover.imgFormat.has(ext)) { const imgPath = path.join(previewDir, file); const tempImgPath = path.join(previewDir, `${file}_temp`); nodeGenWatermark({ img: imgPath, text: '创意素材铺', filepath: tempImgPath, }) .then(() => { // 处理完后,将临时文件重命名为原始文件 fs.rename(tempImgPath, imgPath, (err) => { if (err) { console.error('重命名失败:', err); } else { console.log('水印添加成功,文件已被覆盖:', imgPath); } }); }) .catch((err) => { console.error('发生错误:', err); }); } });