本文介绍使用 Node.js 给图片添加水印的实现方法。我们可以借助 Sharp 库来处理图片,还可以结合 CanvasJimp 实现更多自定义水印效果。以下是两种实现方式:

1. 使用 Sharp 实现水印

Sharp 是一个高性能的图片处理库,适合在 Node.js 环境中使用。

安装依赖

npm install sharp

示例代码

const sharp = require('sharp');

async function addWatermark(inputImage, watermarkImage, outputImage) {
    try {
        // 读取原始图片和水印图片
        const originalImage = sharp(inputImage);
        const { width, height } = await originalImage.metadata();

        const watermark = await sharp(watermarkImage)
            .resize(Math.round(width * 0.3)) // 调整水印宽度为原图的30%
            .toBuffer();

        // 合成图片
        await originalImage
            .composite([
                {
                    input: watermark,
                    gravity: 'southeast', // 设置水印位置,右下角
                },
            ])
            .toFile(outputImage);

        console.log(`水印已添加,输出文件:${outputImage}`);
    } catch (error) {
        console.error('添加水印失败:', error);
    }
}

// 调用函数
addWatermark('input.jpg', 'watermark.png', 'output.jpg');

效果

  • 原始图片:input.jpg
  • 水印图片:watermark.png (透明背景效果更佳)
  • 输出图片:output.jpg

2. 使用 Canvas 实现文字水印

如果需要动态添加文字水印,可以使用 Canvas

安装依赖

npm install canvas

示例代码

const { createCanvas, loadImage } = require('canvas');
const fs = require('fs');

async function addTextWatermark(inputImage, outputImage, text) {
    try {
        const image = await loadImage(inputImage);
        const canvas = createCanvas(image.width, image.height);
        const ctx = canvas.getContext('2d');

        // 绘制原图
        ctx.drawImage(image, 0, 0);

        // 设置水印样式
        const fontSize = Math.round(image.width * 0.05);
        ctx.font = `${fontSize}px Arial`;
        ctx.fillStyle = 'rgba(255, 255, 255, 0.5)'; // 白色半透明
        ctx.textAlign = 'right';
        ctx.textBaseline = 'bottom';

        // 添加水印文字
        ctx.fillText(text, image.width - 20, image.height - 20);

        // 保存输出图片
        const buffer = canvas.toBuffer('image/jpeg');
        fs.writeFileSync(outputImage, buffer);

        console.log(`文字水印已添加,输出文件:${outputImage}`);
    } catch (error) {
        console.error('添加文字水印失败:', error);
    }
}

// 调用函数
addTextWatermark('input.jpg', 'output.jpg', '© YourBrand');

效果

  • 原始图片:input.jpg
  • 水印内容:© YourBrand
  • 输出图片:output.jpg

比较两种方法

方法适用场景优势缺点
Sharp图片水印(图片合成)高性能,简单,支持透明水印不适合动态文字生成
Canvas文字水印、复杂自定义灵活,适合动态内容(如时间戳、品牌标识)性能稍低,依赖更多

根据需求选择适合的方法。如果处理大量图片且需要动态文字,Canvas 是更好的选择;如果只是简单添加图像水印,推荐 Sharp