原文链接:《使用nodejs将PNG图片转成JPG图片》
事件的起因
之前在做网站写文章的时候并没有留意图片格式,只是认为图片能看就行。后来突然想起每次之前上课时老师不断强调要将图片转成JPG格式给她,后来我一查就发现了我犯了一个巨大的错误!
PNG(Portable Network Graphics)和JPG(Joint Photographic Experts Group)是两种常见的图片文件格式,它们主要的区别就是在不同的压缩编码后,呈现的文件大小截然不同而且是非常大的区别!
想知道详细的JPG图片和PNG图片的区别,可以看看看这篇文章 -->点击创送
可以看到同样的图片内容,同样的分辨率,但文件大小相差数倍,这对于一个网站来说,传输一张接近4MB的图片和一张只要500多KB的图片完全是两码事,毕竟带宽和流量都是要花钱的呀!而且图片越大,网页响应速度就越慢,这对于用户来说肯定是非常难受的。所以我开始了轰轰烈烈的图片格式转换工程!
一开始我是使用Photoshop一张一张转,后来发现我又犯傻了,几千张图片一张张转得转到猴年马月呀!为什么不自己写一个脚本来转呢?本着自己动手,丰衣足食的道理,我开始研究使用nodejs将PNG图片转成JPG图片。
下面是要使用到的插件,直接使用npm下载:
// 文件管理插件
npm install fs
// 路径插件
npm install path
// jimp是主要用图片转换的插件
npm install jimp
然后是在这个nodejs项目文件夹中创建两个文件夹作为输入文件夹和输出文件夹,输入文件夹主要是放置要转换的图片文件,输出文件夹就是存储转换后的图片文件。
实现代码
主要的代码部分,创建一个server.js文件,直接复制粘贴下面的代码,然后再cmd窗口输入node server.js执行就行。当然要注意输入文件夹和输出文件夹的路径。
const fs = require('fs');
const path = require('path');
const Jimp = require('jimp');
// 输入文件夹路径
const inputFolder = 'input';
// 输出文件夹路径
const outputFolder = 'output';
// 确保输出文件夹存在
if (!fs.existsSync(outputFolder)) {
fs.mkdirSync(outputFolder);
}
// 读取输入文件夹中的所有文件
fs.readdir(inputFolder, (err, files) => {
if (err) {
console.error('无法读取输入文件夹:', err);
return;
}
// 定义一个递归函数来处理每个文件
const processFile = (index) => {
if (index >= files.length) {
console.log('所有文件处理完成');
return;
}
const file = files[index];
const filePath = path.join(inputFolder, file);
const fileExt = path.extname(file).toLowerCase();
const handleNext = (err) => {
if (err) {
console.error(`处理失败: $https://charhoo.cn/file`, err);
}
processFile(index + 1); // 处理下一个文件
};
if (fileExt === '.webp') {
// 如果是 PNG 文件,转换为 JPG 并导出
const outputFilePath = path.join(outputFolder, path.basename(file, fileExt) + '.webp');
Jimp.read(filePath)
.then(image => {
image.quality(80) // 设置 JPG 质量,范围是 0-100
.write(outputFilePath, () => handleNext());
})
.catch(handleNext);
} else if (fileExt === '.webp' || fileExt === '.webp') {
// 如果是 JPG 或 JPEG 文件,直接复制到输出文件夹
const outputFilePath = path.join(outputFolder, file);
fs.copyFile(filePath, outputFilePath, handleNext);
} else {
// 如果不是图片文件,直接处理下一个文件
handleNext();
}
};
// 开始处理第一个文件
processFile(0);
});
这个脚本的工作流程
定义输入文件夹和输出文件夹的路径。
确保输出文件夹存在,如果不存在则创建它。
使用 fs.readdir 读取输入文件夹中的所有文件。
定义一个递归函数 processFile 来处理每个文件:
- 如果当前文件是 PNG 文件,使用 jimp 库将其转换为 JPG 并保存到输出文件夹。
- 如果当前文件是 JPG 或 JPEG 文件,直接使用 fs.copyFile 复制到输出文件夹。
- 如果转换或复制成功,调用 handleNext 函数处理下一个文件,不输出文字提示。
- 如果转换或复制失败,调用 handleNext 函数处理下一个文件,并输出错误信息。
当然,如果闲麻烦的话可以使用格式工程这个软件来转换,那为什么我不直接使用格式工厂呢?其实是我忘记有这东西了,我也是在写这篇文章的时候才想起来格式工厂可以直接批量转文件格式。
当然现在有一种新的图片格式,WebP格式,虽然现代的主流浏览器都支持WebP格式,但不怕一万就怕万一,还是使用传统的JPG格式稳妥一点。