tinyPNG(小熊猫) + nodejs 实现批量压缩并保存至对应文件夹下

作为一个前端抠图仔,我经常会进行一些图片压缩,常用的就是 tinyPng了。然而网页端的一次只支持上传压缩 20 张图片,操作起来比较繁琐,压缩完保存也是一件比较麻烦的事。

所以突然就有了使用 nodejs 写一个程序来简化这些操作。面向百度后,得知 tinyPNG 有提供相应的 API,那么接下来就是自己动手丰衣足食了。

准备工作

编写程序

生成对应保存图片的文件夹

const {
    statSync,
    readdirSync,
    readFileSync,
    mkdirSync,
    mkdir,
    rmdirSync,
    rmdir,
    writeFileSync,
    writeFile
} = require('fs')
const {
    resolve
} = require('path')
const colors = require('colors-console')
const DIR_NAME = resolve(__dirname, 'images') // 未压缩之前的存放地址
const NEW_DIR_NAME = resolve(__dirname, 'new_images') // 压缩之后的图片地址
/**
 * 
 * @param {String} path  未压缩之前的存放地址
 * @param {String} newFilePath 压缩之后的图片地址
 */
const compress = (path, newFilePath) => {
    const files = readdirSync(path) // 读取文件目录
    if (files.length > 0) {
        files.map(item => {
            let filePath = resolve(path, item) // 文件/文件夹地址
            let newPath = resolve(newFilePath, item) // 将要保存的文件/文件夹地址
            let stats = statSync(filePath) // 获取文件/文件夹的描述信息
            if (stats.isDirectory()) { // 如果是文件夹
                console.group(colors('cyan', `文件夹 ${item} 信息`));
                console.log(colors('cyan', `这是一个文件夹,地址为${filePath}`));
                console.log(colors('cyan', `新的地址为:${newPath}`));
                console.groupEnd();
                rmdir(newPath, { // 先删除,避免创建已有的文件时报错,造成阻塞
                    recursive: true // 设置该属性删除的时候将会遍历整个文件夹
                }, () => {
                    mkdir(newPath, (err) => {// 创建文件夹
                        if (err) throw err
                        console.log(colors('green', `创建成功:${newPath}`))
                        compress(filePath, newPath) // 继续执行遍历文件夹,创建完整目录
                    })
                })
            } 
        })
    }
}
复制代码

微信图片_20210709114745.png

处理文件

const tinify = require("tinify");
tinify.key = 'your key'
const compress = (path, newFilePath) => {
    const files = readdirSync(path) // 读取文件目录
    if (files.length > 0) {
        files.map(item => {
            let filePath = resolve(path, item) // 文件/文件夹地址
            let newPath = resolve(newFilePath, item) // 将要保存的文件/文件夹地址
            let stats = statSync(filePath) // 获取文件/文件夹的描述信息
            if (stats.isDirectory()) { // 如果是文件夹
                console.group(colors('cyan', `文件夹 ${item} 信息`));
                console.log(colors('cyan', `这是一个文件夹,地址为${filePath}`));
                console.log(colors('cyan', `新的地址为:${newPath}`));
                console.groupEnd();
                rmdir(newPath, { // 先删除,避免创建已有的文件时报错,造成阻塞
                    recursive: true // 设置该属性删除的时候将会遍历整个文件夹
                }, () => {
                    mkdir(newPath, (err) => {// 创建文件夹
                        if (err) throw err
                        console.log(colors('green', `创建成功:${newPath}`))
                        compress(filePath, newPath) // 继续执行遍历文件夹,创建完整目录
                    })
                })
            } 
        })
    }else if (stats.isFile()) { // 如果是文件
                console.group(colors('blue', `文件 ${item} 信息`));
                console.log(colors('blue', `这是一个文件,地址为${filePath}`));
                console.groupEnd();
                // tinyPNG 只支持压缩 jpg、png 格式
                let itemSplit = item.split('.')
                if (itemSplit[1] !== 'jpg' && itemSplit[1] !== 'png' && itemSplit[1] !== 'jpeg') { 
                    console.log(colors('red', `当前文件格式为${itemSplit[1]},只支持压缩 jpg、png、jpeg 等!`));
                    return
                }
                const sourceData = readFileSync(filePath)
                tinify.fromBuffer(sourceData).toBuffer(function (err, resultData) {
                    if (err) throw err;
                    writeFile(newPath, resultData, (err) => {
                        if (err) throw err;
                        console.log(colors('yellow', `压缩并保存成功:${newPath}`));
                    });
                });
            }
}
复制代码

完整代码

const {
    statSync,
    readdirSync,
    readFileSync,
    mkdirSync,
    mkdir,
    rmdirSync,
    rmdir,
    writeFileSync,
    writeFile
} = require('fs')
const {
    resolve
} = require('path')
const colors = require('colors-console')
const tinify = require("tinify");
tinify.key = 'your key'
const DIR_NAME = resolve(__dirname, 'images') // 未压缩之前的存放地址
const NEW_DIR_NAME = resolve(__dirname, 'new_images') // 压缩之后的图片地址
/**
 * 
 * @param {String} path  未压缩之前的存放地址
 * @param {String} newFilePath 压缩之后的图片地址
 */
const compress = (path, newFilePath) => {
    const files = readdirSync(path) // 读取文件目录
    if (files.length > 0) {
        files.map(item => {
            let filePath = resolve(path, item) // 文件/文件夹地址
            let newPath = resolve(newFilePath, item) // 将要保存的文件/文件夹地址
            let stats = statSync(filePath) // 获取文件/文件夹的描述信息
            if (stats.isDirectory()) { // 如果是文件夹
                console.group(colors('cyan', `文件夹 ${item} 信息`));
                console.log(colors('cyan', `这是一个文件夹,地址为${filePath}`));
                console.log(colors('cyan', `新的地址为:${newPath}`));
                console.groupEnd();
                rmdir(newPath, { // 先删除,避免创建已有的文件时报错,造成阻塞
                    recursive: true // 设置该属性删除的时候将会遍历整个文件夹
                }, () => {
                    mkdir(newPath, (err) => {// 创建文件夹
                        if (err) throw err
                        console.log(colors('green', `创建成功:${newPath}`))
                        compress(filePath, newPath)  // 继续执行遍历文件夹,创建完整目录
                    })
                })
            } else if (stats.isFile()) { // 如果是文件
                console.group(colors('blue', `文件 ${item} 信息`));
                console.log(colors('blue', `这是一个文件,地址为${filePath}`));
                console.groupEnd();
                // 由于 
                let itemSplit = item.split('.')
                if (itemSplit[1] !== 'jpg' && itemSplit[1] !== 'png' && itemSplit[1] !== 'jpeg') { 
                    console.log(colors('red', `当前文件格式为${itemSplit[1]},只支持压缩 jpg、png、jpeg 等!`));
                    return
                }
                const sourceData = readFileSync(filePath)
                tinify.fromBuffer(sourceData).toBuffer(function (err, resultData) {
                    if (err) throw err;
                    writeFile(newPath, resultData, (err) => {
                        if (err) throw err;
                        console.log(colors('yellow', `压缩并保存成功:${newPath}`));
                    });
                });
            }
        })
    }
}
compress(DIR_NAME, NEW_DIR_NAME)
复制代码

微信图片_20210709120642.png

!!!完结撒花

首文,希望大家多多指教

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享