翼度科技»论坛 编程开发 JavaScript 查看内容

node图片自动压缩

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
图片压缩
借用了images、imagemin等第三方库,压缩jpg、Png图片
viteImagemin也可以实现,代码量更加少,squoosh就没用过了
输入需要压缩的文件
  1. //判断是否已经有这个文件路径
  2. function setInputName() {
  3.     return new Promise((resolve, reject) => {
  4.         inputVlaue.question('请输入需要压缩文件夹名称:', async (val) => {
  5.             let asr = val.replace(/\s+/g, "");
  6.             if (asr == 'imagesTest') {
  7.                 console.log("不可以与默认输出文件夹重名");
  8.                 return setFileName("请重新输入!\n")
  9.             } else if (!reg.test(asr)) {
  10.                 console.log("只能输入英文");
  11.                 return setFileName("请重新输入!\n")
  12.             }
  13.             positionDir = path.join(process.cwd(), asr)
  14.             console.log(positionDir);
  15.             resolve(positionDir)
  16.         })
  17.     })
  18. }
复制代码
不存在则自动创建文件

不建议在调用 fs.open() 、fs.readFile() 或 fs.writeFile() 之前使用 fs.stat() 检查一个文件是否存在。 作为替代,用户代码应该直接打开/读取/写入文件,当文件无效时再处理错误。
如果要检查一个文件是否存在且不操作它,推荐使用 fs.access()
这里使用node内置path处理文件
  1. function createTimeFile(positionDir) {
  2.     let time_PATH = path.resolve(__dirname, positionDir);//获取是否已经存在这个文件
  3.     return new Promise((resolve, reject) => {
  4.         fs.stat(time_PATH, (err, stat) => {
  5.             if (err) {
  6.                 fs.mkdir(positionDir, { recursive: true }, (err) => {
  7.                     resolve(err)
  8.                     console.log(`创建${positionDir}成功!`);
  9.                 })
  10.             } else {
  11.                 resolve(stat)
  12.             }
  13.         })
  14.     })
  15. }
复制代码
文件创建成功,输入xx指令进行压缩
  1. function ready() {
  2.     let msg=`请把所需压缩图片放入${positionDir}输入yes,开始压缩图片!\n`
  3.     inputVlaue.question(msg, answers => {
  4.         let asr = answers.trim().toLocaleLowerCase()
  5.         if (asr == "yes") {
  6.             console.log("开始压缩...\n");
  7.             setImageData()
  8.         } else {
  9.             ready("指令错误请重新输入,输入yes开始压缩图片\n")
  10.         }
  11.     })
  12. }
复制代码
读取需要压缩的文件
  1. //读取需要压缩的文件夹
  2. function getReadFile() {
  3.     fs.readdir(positionDir, "utf-8", (err, data) => {
  4.         console.log(data.length);
  5.         if (data.length == 0) {
  6.             console.log("还没有图片,请添加");
  7.         }
  8.         data.forEach((item, index) => {
  9.             let filePath = path.join(positionDir, item)
  10.             let filename = filePath.replace(/\\/g, "/");//把 \ 替换为 /
  11.             let output = filename.replace(positionDir.replace(/\\/g, "/"), outputDir.replace(/\\/g, "/"));//输出位置
  12.             if (path.extname(item) == ".png") {
  13.                 pngArrayList.push({ filename, output })
  14.             } else if (path.extname(item) == ".jpg") {
  15.                 jpgArrayList.push({ filename, output })
  16.             } else if (fs.statSync(filePath).isDirectory()) {
  17.                 readfile(filePath)
  18.             }
  19.         })
  20.     })
  21. }
复制代码
针对jpg和png处理使用不同的方法
  1. function setImageData() {
  2.     if (jpgArrayList.length != 0) {
  3.         jpgArrayList = rmSame(jpgArrayList)
  4.         //压缩jpg
  5.         console.log(jpgArrayList);
  6.         jpgArrayList.forEach(item => {
  7.             createTimeFile(path.dirname(item.output))
  8.             images(item.filename).save(item.output, { quality: 60 })
  9.         })
  10.     }
  11.     //压缩png
  12.     pngArrayList = rmSame(pngArrayList)
  13.     pngCompress(pngArrayList, pngArrayList.length - 1)
  14. }
  15. function rmSame(arr) {
  16.     let newArray = []
  17.     let arrObj = []
  18.     for (let index = 0; index < arr.length; index++) {
  19.         const element = arr[index];
  20.         if (newArray.indexOf(element['filename']) == -1 && (fs.statSync(element['filename']).size > 1024)) {
  21.             newArray.push(element['filename'])
  22.             arrObj.push(element)
  23.         } else if (newArray.indexOf(element['filename']) == -1 && (fs.statSync(element['filename']).size <= 1024)) {
  24.             let pathDir = path.dirname(element['output'])
  25.             createTimeFile(pathDir)//判断存放压缩的文件夹是否已经存在,不存在则创建
  26.             fs.createReadStream(element['filename']).pipe(fs.createWriteStream(element['output']))
  27.             console.log(`图片${element['filename']}内存过小,直接转移到${element['output']}`)
  28.         }
  29.     }
  30.     return arrObj
  31. }
  32. //png压缩图片
  33. function pngCompress(arr, index) {
  34.     //压缩结束
  35.     if (index < 0) {
  36.         console.log("\n本窗口在5秒后关闭!")
  37.         setTimeout(() => {
  38.             inputVlaue.close()
  39.         }, 5000)
  40.         return
  41.     }
  42.     let pathDir = path.dirname(arr[index]['output'])
  43.     let filename = arr[index]['filename']
  44.     createTimeFile(pathDir)
  45.     imagemin([filename], {
  46.         destination: pathDir,
  47.         plugins: [
  48.             imageminPngquant({
  49.                 quality: [0.6, 0.7]
  50.             })
  51.         ]
  52.     }).then(() => {
  53.         console.log(`图片${filename}压缩完成!`);
  54.         pngCompress(arr, index - 1)
  55.     }).catch(err => {
  56.         console.log(`${arr[index]['filename']}图片压缩不了了,直接转移到${arr[index]['output']}`)
  57.         fs.createReadStream(arr[index]['filename']).pipe(fs.createWriteStream(arr[index]['output']))
  58.         pngCompress(arr, index - 1)
  59.     });
  60. }
复制代码
全部代码
  1. /* * @Author: zlc * @Date: 2022-04-14 16:34:12 * @LastEditTime: 2022-04-15 10:26:16 * @LastEditors: zlc * @Description: 图片压缩 * @FilePath: \git项目\project-template\案例\图片压缩\imagemin\src\app.js */const fs = require("fs")const imagemin = require('imagemin');const imageminPngquant = require('imagemin-pngquant');const path = require("path")const images = require("images")const readline = require("readline");const { resolve } = require("path");const inputVlaue = readline.createInterface({    input: process.stdin,    output: process.stdout});let outputDir = path.join(process.cwd(), "imagesTest")let reg = /^[a-zA-Z]+$/let positionDir, timeId, pngArrayList = [], jpgArrayList = []let timeIndex = 0const setCompress = async () => {    await setInputName();//输入内容    await createTimeFile(positionDir);//创建文件    await getReadFile()//读取文件    ready()//开始压缩        }//判断是否已经有这个文件路径
  2. function setInputName() {
  3.     return new Promise((resolve, reject) => {
  4.         inputVlaue.question('请输入需要压缩文件夹名称:', async (val) => {
  5.             let asr = val.replace(/\s+/g, "");
  6.             if (asr == 'imagesTest') {
  7.                 console.log("不可以与默认输出文件夹重名");
  8.                 return setFileName("请重新输入!\n")
  9.             } else if (!reg.test(asr)) {
  10.                 console.log("只能输入英文");
  11.                 return setFileName("请重新输入!\n")
  12.             }
  13.             positionDir = path.join(process.cwd(), asr)
  14.             console.log(positionDir);
  15.             resolve(positionDir)
  16.         })
  17.     })
  18. }//创建图片文件function createTimeFile(positionDir) {
  19.     let time_PATH = path.resolve(__dirname, positionDir);//获取是否已经存在这个文件
  20.     return new Promise((resolve, reject) => {
  21.         fs.stat(time_PATH, (err, stat) => {
  22.             if (err) {
  23.                 fs.mkdir(positionDir, { recursive: true }, (err) => {
  24.                     resolve(err)
  25.                     console.log(`创建${positionDir}成功!`);
  26.                 })
  27.             } else {
  28.                 resolve(stat)
  29.             }
  30.         })
  31.     })
  32. }//读取需要压缩的文件夹
  33. function getReadFile() {
  34.     fs.readdir(positionDir, "utf-8", (err, data) => {
  35.         console.log(data.length);
  36.         if (data.length == 0) {
  37.             console.log("还没有图片,请添加");
  38.         }
  39.         data.forEach((item, index) => {
  40.             let filePath = path.join(positionDir, item)
  41.             let filename = filePath.replace(/\\/g, "/");//把 \ 替换为 /
  42.             let output = filename.replace(positionDir.replace(/\\/g, "/"), outputDir.replace(/\\/g, "/"));//输出位置
  43.             if (path.extname(item) == ".png") {
  44.                 pngArrayList.push({ filename, output })
  45.             } else if (path.extname(item) == ".jpg") {
  46.                 jpgArrayList.push({ filename, output })
  47.             } else if (fs.statSync(filePath).isDirectory()) {
  48.                 readfile(filePath)
  49.             }
  50.         })
  51.     })
  52. }function ready() {
  53.     let msg=`请把所需压缩图片放入${positionDir}输入yes,开始压缩图片!\n`
  54.     inputVlaue.question(msg, answers => {
  55.         let asr = answers.trim().toLocaleLowerCase()
  56.         if (asr == "yes") {
  57.             console.log("开始压缩...\n");
  58.             setImageData()
  59.         } else {
  60.             ready("指令错误请重新输入,输入yes开始压缩图片\n")
  61.         }
  62.     })
  63. }function setImageData() {
  64.     if (jpgArrayList.length != 0) {
  65.         jpgArrayList = rmSame(jpgArrayList)
  66.         //压缩jpg
  67.         console.log(jpgArrayList);
  68.         jpgArrayList.forEach(item => {
  69.             createTimeFile(path.dirname(item.output))
  70.             images(item.filename).save(item.output, { quality: 60 })
  71.         })
  72.     }
  73.     //压缩png
  74.     pngArrayList = rmSame(pngArrayList)
  75.     pngCompress(pngArrayList, pngArrayList.length - 1)
  76. }
  77. function rmSame(arr) {
  78.     let newArray = []
  79.     let arrObj = []
  80.     for (let index = 0; index < arr.length; index++) {
  81.         const element = arr[index];
  82.         if (newArray.indexOf(element['filename']) == -1 && (fs.statSync(element['filename']).size > 1024)) {
  83.             newArray.push(element['filename'])
  84.             arrObj.push(element)
  85.         } else if (newArray.indexOf(element['filename']) == -1 && (fs.statSync(element['filename']).size <= 1024)) {
  86.             let pathDir = path.dirname(element['output'])
  87.             createTimeFile(pathDir)//判断存放压缩的文件夹是否已经存在,不存在则创建
  88.             fs.createReadStream(element['filename']).pipe(fs.createWriteStream(element['output']))
  89.             console.log(`图片${element['filename']}内存过小,直接转移到${element['output']}`)
  90.         }
  91.     }
  92.     return arrObj
  93. }
  94. //png压缩图片
  95. function pngCompress(arr, index) {
  96.     //压缩结束
  97.     if (index < 0) {
  98.         console.log("\n本窗口在5秒后关闭!")
  99.         setTimeout(() => {
  100.             inputVlaue.close()
  101.         }, 5000)
  102.         return
  103.     }
  104.     let pathDir = path.dirname(arr[index]['output'])
  105.     let filename = arr[index]['filename']
  106.     createTimeFile(pathDir)
  107.     imagemin([filename], {
  108.         destination: pathDir,
  109.         plugins: [
  110.             imageminPngquant({
  111.                 quality: [0.6, 0.7]
  112.             })
  113.         ]
  114.     }).then(() => {
  115.         console.log(`图片${filename}压缩完成!`);
  116.         pngCompress(arr, index - 1)
  117.     }).catch(err => {
  118.         console.log(`${arr[index]['filename']}图片压缩不了了,直接转移到${arr[index]['output']}`)
  119.         fs.createReadStream(arr[index]['filename']).pipe(fs.createWriteStream(arr[index]['output']))
  120.         pngCompress(arr, index - 1)
  121.     });
  122. }setCompress()
复制代码
git地址:https://gitee.com/KingSio/project-template/tree/master/

来源:https://www.cnblogs.com/shukesio/p/17761283.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具