当前位置: 首页 > 后端技术 > Node.js

Nodejs自动使用Tinypng(免费版,无需配置)压缩图片

时间:2023-04-03 17:44:08 Node.js

##无需任何插件,免费CV,一行命令搞定:node./tinypng.js-f./test-deep总体思路:递归获取本地文件夹中的文件过滤文件,格式必须为.jpg.png,且大小小于5MB。(文件夹递归)一次只处理一个文件(可以绕过20个的限制)处理返回的数据,得到远程优化后的图片地址取回图片更新本地图片纯节点实现,不依赖任何其他代码片段`/***帮助文档*------**获取帮助*command-h**获取命令执行文件夹*command-f*参数./*必填,待处理图片文件夹**是否获取depth递归处理图像文件夹*Command-deep*可选,默认没有深度递归**命令行脚本参考示例*>node./tinypng.js-f./test-deep**/constfs=require('fs');constpath=require('路径');consthttps=require('https');constURL=require('url').URL;constEventEmitter=require('事件');consterr=msg=>newEventEmitter().emit('error',msg);如果(getHelp())返回false;constconf={files:[],EntryFolder:getEntryFolder(),DeepLo??op:getDeepLo??op(),Exts:['.jpg','.png'],Max:5200000,//5MB==5242848.754299136}fileFilter(conf.EntryFolder)console.log("本次执行脚本的配置:",conf);console.log("等待处理的文件个数:",conf.files.length)conf.files.forEach(img=>fileUpload(img));////////////////////////////////工具函数/***获取帮助命令*指令-h*/functiongetHelp(){leti=process.argv.findIndex(i=>i==="-h");if(i!==-1){console.log(*帮助文档*------**获取帮助*command-h**获取命令执行文件夹*command-f*parameter./*必填,待处理图片文件夹**获取是否深度递归处理图片文件夹*说明-deep*可选,默认不深度递归**>node./tinypng.js-f./test-deep)returntrue;}}/***获取命令ExecuteFolder*Command-f*Parameter./*必填,待处理的图片文件夹*/functiongetEntryFolder(){leti=process.argv.findIndex(i=>i===“-F”);if(i===-1||!process.argv[i+1])returnerr('获取命令执行文件夹:失败');returnprocess.argv[i+1];}/***get是否深度递归处理图片文件夹*指令-deep*可选,默认不深度递归*/functiongetDeepLo??op(){returnprocess.argv.findIndex(i=>i==="-deep")!==-1;}/***过滤待处理文件夹得到待处理文件列表*@param{*}folder待处理文件夹*@param{*}files待处理文件列表*/functionfileFilter(folder){//读取文件夹fs.readdirSync(folder).forEach(file=>{letfullFilePath=path.join(folder,file)//读取文件信息letfileStat=fs.statSync(fullFilePath);//过滤文件安全/大小限制/后缀名if(fileStat.size<=conf.Max&&fileStat.isFile()&&conf.Exts.includes(path.extname(file)))conf.files.push(fullFilePath);//必须递归处理文件夹elseif(conf.DeepLo??op&&fileStat.isDirectory())fileFilter(fullFilePath);});}/***TinyPng远程压缩HTTPS请求配置生成方法*/functiongetAjaxOptions(){return{method:'POST',hostname:'tinypng.com',路径:'/web/shrink',标头:{rejectUnauthorized:false,“X-Forwarded-For”:Array(4).fill(1).map(()=>parseInt(Math.random()*254+1).join('.'),'Postman-Token':Date.now(),'Cache-Control':'no-cache','Content-Type':'application/x-www-form-urlencoded','User-Agent':'Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/56.0.2924.87Safari/537.36'}}}/***TinyPng远程压缩HTTPS请求*@param{string}要处理的img文件*@success{*“输入”:{“大小”:887,“类型”:“图像/PNG”},*“输出”:{“大小”:785,“类型”:“图像/PNG”,“宽度”:81,“高度”:81,“比率”:0.885,“url”:“https://tinypng.com/web/output/7aztz90nq5p9545zch8gjzqg5ubdatd6”}*}*@error{“错误”:“错误请求”,“message":"Requestisinvalid"}*/functionfileUpload(imgPath){letreq=https.request(getAjaxOptions(),(res)=>{res.on('data',buf=>{letobj=JSON.parse(buf.toString());if(obj.error)console.log(compressionfailed!\ncurrentfile:${imgPath}\n${obj.message});elsefileUpdate(imgPath,obj);});});req.write(fs.readFileSync(imgPath),'binary');req.on('error',e=>console.error(请求错误!\n当前文件:${imgPath}\n,e));要求。结尾();}//循环调用此方法请求图片数据functionfileUpdate(entryImgPath,obj){letoptions=newURL(obj.output.url);letreq=https.request(options,res=>{letbody='';res.setEncoding('binary');res.on('data',(data)=>body+=data);res.on('end',()=>{fs.writeFile(entryImgPath,body,'binary',err=>{if(err)returnconsole.error(err);让log=压缩成功,log+=优化比例:${((1-obj.output.ratio)*100).toFixed(2)}%,log+=原始大小:${(obj.input.size/1024).toFixed(2)}KB,log+=压缩大小:${(obj.output.size/1024).toFixed(2)}KB,log+=file:${entryImgPath}console.log(log);});});});req.on('error',e=>console.error(e));req.end();}//节点./tinypng.js-f./static/smp/m/course_task`