日期: 2021/08/18 天气:晴
/** @Description: 多张图片上传压缩* @Author: 惜神* @Date: 2021-08-17 16:45:27*/const fs = require("fs");const JSZip = require("jszip");const image = require("imageinfo");const zip = new JSZip();const request = require('request');const path = require('path');const QRCode = require('qrcode');/*** 创建新的文件夹用于保存图片(如果有自己的文件夹,可以不使用)* @author: 惜神* @param {String} dirname 创建文件路径* @Date: 2021-08-17 17:36:07*/const mkdirSync = (dirname) => {if (fs.existsSync(dirname)) {return true;} else {if (mkdirSync(path.dirname(dirname))) {fs.mkdirSync(dirname);return true;}}return false}/*** @author: 惜神* @param {String} folderPaths 压缩文件路径* @param {String} outPath 压缩文件输出路径* @Date: 2021-08-17 17:35:13*/const packZipList = (folderPaths, outPath) => {const lists = getFiles.getFileList(folderPaths); //获取文件夹里的所有图片文件值for (let i = 0; i < lists.length; i++) {const data = fs.readFileSync(`${folderPaths}${lists[i].filename}`);const suffix = lists[i].filename.split('.')[1];zip.file(`photo_${i}.${suffix}`, data, { base64: true });delFile(`${folderPaths}${lists[i].filename}`, folderPaths) //调用删除方法}zip.generateNodeStream({ type: 'nodebuffer', streamFiles: true }).pipe(fs.createWriteStream(outPath)) //打包后的包名可以自己根据需求定义,路径可以根据需求更改.on('finish', () => {console.log(`${outPath} written.`); //管道写完数据后,打印出提示});}/*** 读取文件list* @author: 惜神* @param {String} path 文件夹路径* @Date: 2021-08-17 17:34:21*/const readFileList = (path, filesList) => {const files = fs.readdirSync(path);files.forEach((item) => {const stat = fs.statSync(`${path}${item}`);if (stat.isDirectory()) {//递归读取文件readFileList(`${path}${item}/`, filesList)} else {let obj = {};//定义一个对象存放文件的路径和名字obj.path = path;//路径obj.filename = item//名字filesList.push(obj);}})}/*** 获取文件* @author: 惜神* @Date: 2021-08-17 17:33:58*/const getFiles = {//获取文件夹下的所有文件getFileList: (path) => {const filesList = [];readFileList(path, filesList);return filesList;},//获取文件夹下的所有图片getImageFiles: (path) => {const imageList = [];this.getFileList(path).forEach((item) => {const ms = image(fs.readFileSync(`${item.path}${item.filename}`));ms.mimeType && (imageList.push(item.filename))});return imageList;}};/*** 检查是否是空文件夹* @author: 惜神* @param {String} file 文件路径* @Date: 2021-08-18 14:07:16*/const fileExists = (file) => {fs.access(`${file}`, fs.constants.F_OK, (err) => {if(err) {return false}fs.readdir(`${file}/`,function(err,fileArr){if(err){return false}if(fileArr.length === 0) {return false}return true})});}/*** 移动文件夹* @author: 惜神* @param {String} dstpath 加载文件夹路径* @param {String} sourcePath 来源文件夹路径* @Date: 2021-08-18 12:16:53*/const mvFiles = (dstpath, sourcePath) => {const status = fileExists(sourcePath);if(!status) return;fs.rename(sourcePath, dstpath, (err) => {if (err) {console.log('move file',err)}mkdirSync(sourcePath)})}/*** 删除文件下的文件* @author: 惜神* @param {String} path 文件夹下所有图片的路径* @param {String} reservePath 文件夹路径* @Date: 2021-08-17 17:26:25*/const delFile = (path, reservePath) => {if (fs.existsSync(path)) {if (fs.statSync(path).isDirectory()) {let files = fs.readdirSync(path);files.forEach((file, index) => {let currentPath = `${path}/${file}`;if (fs.statSync(currentPath).isDirectory()) {delFile(currentPath, reservePath);} else {fs.unlinkSync(currentPath);}});if (path != reservePath) {fs.rmdirSync(path);}} else {fs.unlinkSync(path);}}}/*** 图片链接处理* @author: 惜神* @param {String} dstpath 打包图片路径* @param {String} imageList 图片数组* @Date: 2021-08-18 12:17:36*/const linkTodo = async (dstpath, imageList) => {if(imageList && imageList.length === 0) return;mkdirSync(dstpath);for (const item of imageList) {const arg = new URL(item);const fileName = arg.pathname.split('/').slice(-1)[0];const downloadUrl = `${dstpath}/${fileName}`;request(item).pipe(fs.createWriteStream(downloadUrl))}}/*** code 处理* @author: 惜神* @param {String} dstpath 打包图片路径* @param {String} codeList code数组* @Date: 2021-08-18 12:18:17*/const codeTodo = async (dstpath, codeList) => {if(codeList && codeList.length === 0) return;mkdirSync(dstpath);codeList.forEach(async (code, index) => {const fileName = `code_${code}_${index}`;const downloadUrl = `${dstpath}/${fileName}.png`;try {await QRCode.toFile(downloadUrl, code, {color: {dark: '#FFFF',light: '#0000'}})} catch (err) {console.error(err)}});}/*** 文件目录处理* @author: 惜神* @param {*} dstpath 打包图片路径* @param {*} sourcePath 来源图片路径* @Date: 2021-08-18 12:19:42*/const folderTodo = async (dstpath, sourcePath) => {await mvFiles(dstpath, sourcePath);}/*** @author: 惜神* @param {String} dstpath 导出文件夹路径* @param {Array} imageList 图片链接* @param {Array} codeList code数组* @param {String} sourcePath 图片来源路径* @param {String} type 属输入类型* @param {String} outPath 压缩图片压缩包输出路径* @Date: 2021-08-17 16:58:47*/(async ({ dstpath = "./img", imageList = [], outPath = "out.zip", type ="link", codeList = [], sourcePath = "./testImage" }) => {const map = {'link': await linkTodo(dstpath, imageList),'folder': await folderTodo(dstpath, sourcePath),'code': await codeTodo(dstpath, codeList)}console.log(type)map[type];const folderPaths = `${dstpath}/`;setTimeout(() => { packZipList(folderPaths, outPath) }, 1000);})(/********* 图片链接参数 **********/{dstpath: "./img",imageList: ["https://cdn-scp.banu.cn/ideas/ideas/1617243660362-448561514.jpeg","https://cdn-scp.banu.cn/ideas/ideas/1617243660548-7283341.jpeg"],outPath: "out.zip",type: "link"}/********** 二维码字符串参数 **********/// {// dstpath: "./img",// codeList: ['1','2','桌位码:32'],// outPath: "out.zip",// type: "code"// }/********** 固定路径图片串参数 **********/// {// dstpath: "./img",// sourcePath: "./testImage",// outPath: "out.zip",// type: "folder"// })
