const sharp = require('sharp'); class ImageProcessor { /** * 为图片添加文字水印 * @param {Buffer} imageBuffer - 原始图片的Buffer数据 * @param {String} text - 水印文字内容 * @param {Object} options - 水印配置选项 * @returns {Promise} - 添加水印后的图片Buffer */ static async addWatermark(imageBuffer, text = '又鸟蛋平台', options = {}) { try { console.log('【图片处理】开始添加水印'); // 设置默认配置 const defaultOptions = { fontSize: 20, // 字体大小 - 减小以确保完整显示 color: 'rgba(0,0,0,0.5)', // 文字颜色(加深以便更清晰) position: 'bottom-right', // 水印位置 marginX: -50, // X轴边距 - 调整使水印居中在红色框中 marginY: 10 // Y轴边距 - 减小使水印靠下,放入红色框中 }; // 强制使用'bottom-right'位置 options.position = 'bottom-right'; const config = { ...defaultOptions, ...options }; // 使用sharp处理图片 const image = sharp(imageBuffer); // 获取图片信息以确定水印位置 const metadata = await image.metadata(); const width = metadata.width || 800; const height = metadata.height || 600; // 确定水印位置 let x = config.marginX; let y = config.marginY; if (config.position === 'bottom-right') { // 右下角位置,需要计算文字宽度(这里简化处理,实际应该根据字体计算) // 这里使用一个简单的估算:每个字符约占字体大小的0.6倍宽度 const estimatedTextWidth = text.length * config.fontSize * 0.6; x = width - estimatedTextWidth - config.marginX; y = height - config.fontSize - config.marginY; } else if (config.position === 'center') { x = (width / 2) - (text.length * config.fontSize * 0.3); y = height / 2; } else if (config.position === 'top-left') { // 左上角,使用默认的margin值 } // 确保位置不会超出图片边界 x = Math.max(0, Math.min(x, width - 1)); y = Math.max(config.fontSize, Math.min(y, height - 1)); // 添加文字水印 const watermarkedBuffer = await image .composite([{ input: Buffer.from(` ${text} `), gravity: 'southeast' }]) .toBuffer(); console.log('【图片处理】水印添加成功'); return watermarkedBuffer; } catch (error) { console.error('【图片处理】添加水印失败:', error.message); console.error('【图片处理】错误详情:', error); // 如果水印添加失败,返回原始图片 return imageBuffer; } } /** * 批量为图片添加水印 * @param {Array} imageBuffers - 图片Buffer数组 * @param {String} text - 水印文字内容 * @param {Object} options - 水印配置选项 * @returns {Promise>} - 添加水印后的图片Buffer数组 */ static async addWatermarkToMultiple(imageBuffers, text = '又鸟蛋平台', options = {}) { try { console.log(`【图片处理】开始批量添加水印,共${imageBuffers.length}张图片`); const watermarkedPromises = imageBuffers.map(buffer => this.addWatermark(buffer, text, options) ); const results = await Promise.all(watermarkedPromises); console.log('【图片处理】批量水印添加完成'); return results; } catch (error) { console.error('【图片处理】批量添加水印失败:', error.message); throw error; } } /** * 为Base64编码的图片添加水印 * @param {String} base64Image - Base64编码的图片 * @param {String} text - 水印文字内容 * @param {Object} options - 水印配置选项 * @returns {Promise} - 添加水印后的图片Buffer */ static async addWatermarkToBase64(base64Image, text = '又鸟蛋平台', options = {}) { try { // 移除Base64前缀 const base64Data = base64Image.replace(/^data:image\/(png|jpeg|jpg|gif);base64,/, ''); // 转换为Buffer const buffer = Buffer.from(base64Data, 'base64'); // 添加水印 return await this.addWatermark(buffer, text, options); } catch (error) { console.error('【图片处理】为Base64图片添加水印失败:', error.message); throw error; } } } module.exports = ImageProcessor;