使用Node.js批量压缩图片

243 阅读3分钟

在 Node.js 中实现一个遍历文件夹并压缩图片的功能,可以通过以下几个步骤来完成:

  1. 使用 fs 模块遍历文件夹。
  2. 使用 sharp 库来压缩图片(sharp 是一个非常高效的图像处理库,支持图像压缩、转换格式等功能)。
  3. 使用 path 模块来处理文件路径。

以下是实现这个功能的代码:

安装依赖

首先,确保你已经安装了 sharp 库和 fs-extra 库(fs-extra 提供了比 fs 更强大的文件操作功能):

npm install sharp fs-extra

代码实现

const fs = require('fs-extra'); // 文件操作
const path = require('path'); // 路径操作
const sharp = require('sharp'); // 图像处理库

// 压缩图片函数
async function compressImage(inputPath, outputPath) {
    try {
        if(path.extname(inputPath) === '.png') {
            await sharp(inputPath)
            .toFormat('png', { quality: 80 }) // 设置输出格式和质量
            .toFile(outputPath);
        } else{
            await sharp(inputPath)
            .toFormat('jpeg', { quality: 80 }) // 设置输出格式和质量
            .toFile(outputPath);
        }
       
        console.log(`图片压缩成功:${outputPath}`);
    } catch (err) {
        console.error(`压缩图片失败:${inputPath}`, err);
    }
}

// 遍历文件夹并处理图片
async function traverseAndCompress(dirPath, targetPath) {
    try {
        const files = await fs.readdir(dirPath); // 读取文件夹内容
        for (let file of files) {
            const filePath = path.join(dirPath, file);
            const target_filePath = path.join(targetPath, file);
            const stat = await fs.stat(filePath); // 获取文件信息

            // 如果是文件夹,则递归遍历
            if (stat.isDirectory()) {
                await traverseAndCompress(filePath, target_filePath);
            } else {
                const extname = path.extname(file).toLowerCase();
                // 只处理图片文件
                if (['.jpg', '.jpeg', '.png'].includes(extname)) {
                    const outputDir = targetPath; //path.join(dirPath, 'compressed'); // 压缩后保存的目录
                    await fs.ensureDir(outputDir); // 确保目标文件夹存在

                    const outputPath = path.join(outputDir, file); // 压缩后的图片路径
                    await compressImage(filePath, outputPath); // 压缩图片
                }
            }
        }
    } catch (err) {
        console.error('遍历文件夹出错:', err);
    }
}

// 传入目标文件夹路径
const directoryPath = './images'; // 替换为你的目标文件夹路径
const targetPath = './images/compressed'; // 替换为你的目标文件夹路径
traverseAndCompress(directoryPath, targetPath);

代码解释

  1. compressImage 函数:使用 sharp 对图像进行压缩。这里的压缩方式质量设置为 80。你可以根据需求调整尺寸和质量。
  2. traverseAndCompress 函数:这个函数会递归地遍历指定文件夹中的所有文件,如果文件是图片(通过扩展名判断),则调用 compressImage 函数来进行压缩。如果遇到子文件夹,函数会递归调用自身来处理子文件夹中的图片。
  3. fs.ensureDir:确保压缩后的图片保存到对应的子文件夹中。
  4. path.extname(file) :判断文件扩展名,确保只处理图片文件。

运行方法

将代码保存在 compressImages.js 文件中,确保你的目标文件夹中有图片。然后运行以下命令来执行压缩操作:

node compressImages.js

进一步的改进

  1. 并发优化:如果你的图片非常多,可以使用并发处理来加速压缩过程,例如使用 Promise.all 或者 async 库来控制并发数。
  2. 错误处理:你可以进一步增强错误处理机制,避免程序在遇到个别错误时中断。
  3. 其他图像处理:可以根据需要调整图像的其他参数(如格式转换、裁剪等)。

这个脚本是一个简单的起点,可以根据实际需要做进一步的修改。