微信联系人背景说明是这个:还是这个:其实是由背景、人物、组件组成图片。假设使用以下素材生成一个NFT盲盒:背景:10种不同颜色人物:10种不同肤色配饰:10种帽子,10种衣服,10种手持物品这么简单的50种素材就已经可以拼接了分为10*10*10*10*10=100,000种不同的组合。保姆级教程,让您开始使用虚拟项目示例。示例项目代码下载:https://download.csdn.net/download/jslygwx/77829790假设项目情况:共100000张图片合成8种材质(背景、人物、肤色、物品、饰品等,共8种)每种提供10张以上素材图片稀有度设置(总概率100%)1/100,2/100,3/100,4/100,10/100,10/100,16/100,17/100、18/100、19/100只是设置这样的概率作为演示。(后续进阶教程会讲到具体的稀有度设置和个性化素材配置。)生成组合先从一个简单的例子说起。例如8种零件,按照0~7的顺序创建文件夹。示例:0背景人物1人物2人物肤色3人物服装4人物帽子。.....//设置总数为100,000constTOTAL=1e5;//类型定义,分别为01234567constTYPE=newArray(8).fill(0).map((_,i)=>i);//部分定义,分别为0123...9//如果超过10个,可以用字母abcde继续排序constCOMP=newArray(10).fill(0).map((_,i)=>i);//0~9部分对应的生成概率constPR=[1/100,2/100,3/100,4/100,10/100,10/100,16/100,17/100,18/100,19/100];constSTART_TIME=newDate();constRESULTS=newSet();//中断并生成constEND_TIME=newDate();console.log(`花费:${END_TIME.getTime()-START_TIME.getTime()}ms`);console.log(JSON.stringify([...RESULTS],null,2));上面的算法(见项目示例代码),生成500万条数据应该也在1s以内。执行结果:Spent:34ms["99696789","64766443","44467446",//...100,000条记录]为什么要使用随机种子。因为这样可以保证所有的组合都刚好符合概率,保证程序的性能。如果觉得生成的结果没有乱序,可以在上面标记排序的位置修改排序规则,或者多次执行sort()进行shuffle。以99696789生成一张图片(单张,一张)以99696789为例:背景:9-第10种常见材质人物:9-第10种常见材质肤色:6-第7种常见材质...把各材质Stitch图片从下往上,生成NFT。生成图片:nodegenerate.js99001122生成单张图片,大概0.5~1.5秒。批量生成NFT图像这里我们可以使用多线程和消息队列。先在本地启动Redis(db0可以清空)。运行一次脚本并将100,000个任务插入队列:import*asfsfrom'fs';import*aspathfrom'path';import{WhiteQ}from'whiteq';constwq=newWhiteQ();constfile=fs.readFileSync(path.join(__dirname,'../100k.log'),'utf-8');consttasks=file.split('\n');wq.addJobs('tasks',tasks.map((t)=>({name:t,data:t}))).then(()=>{process.exit(0);}).catch(控制台错误);然后使用PM2执行这个脚本来执行多线程生成任务:const{WhiteQ}=require('whiteq');const{execSync}=require('child_process');constpath=require('路径');constwq=newWhiteQ();wq.worker('tasks',async(job)=>{console.log(job.name);constresult=execSync(`node${path.join(__dirname,'generate.js')}${job.name}`,{encoding:'utf-8'});if(result.includes('Timespent')){returntrue;}console.log(result);returnfalse;});实测10万张图片生成的话,大概需要5个小时;10,000张图片,不到半小时。图片压缩可以清除原来的Redis记录,重新插入到任务队列中。使用pngquant压缩,可以将原来3MB的png图片压缩到100~300KB。批量重命名压缩图片的文件后缀都是-fs8.png。如果要去掉,可以使用批量重命名的方法:const{WhiteQ}=require('whiteq');const{execSync}=require('child_process');constpath=require('path');constwq=newWhiteQ();wq.worker('tasks',async(job)=>{console.log(job.name);execSync(`rm-rf${path.join(__dirname,`../output/${job.name}.png`)}`);execSync(`mv${path.join(__dirname,`../output/${job.name}-fs8.png`)}${path.join(__dirname,`../output/${job.name}.png`)}`);返回真;});进阶教程你可以对零件的类型,每个零件的元素个数,每个元素的掉落概率有自定义的要求,那么你可以参考这个生成脚本来生成组合:constTOTAL=1e5;constSTART_TIME=newDate();constPR={'1background':[8.8/100,9.0/100,8.7/100,9.1/100,9.0/100,8.9/100,9.2/100,8.8/100,8.5/100,10/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100],'2skin':[9.1/100,9.2/100,9.3/100,9.0/100,9.1/100,8.4/100,9.7/100,8.5/100,9.9/100,8.8/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100],'3clothes':[9.1/100,9.2/100,9.3/100,9.0/100,9.1/100,8.4/100,9.7/100,8.5/100,9.9/100,8.8/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100],'4necklace':[9.1/100,10.5/100,10.1/100,10.6/100,9.1/100,9.0/100,10.7/100,9.2/100,9.9/100,10.8/100,1/100],'5bag':[9.6/100,10.5/100,10.1/100,10.6/100,9.1/100,9.5/100,10.7/100,9.2/100,9.9/100,10.8/100],'6head':[9.1/100,9.3/100,10.1/100,9.4/100,9.1/100,9.0/100,9.4/100,9.2/100,9.0/100,9.4/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100],'7glasses':[9.1/100,9.2/100,9.3/100,9.2/100,9.1/100,8.8/100,9.7/100,8.9/100,8.9/100,8.8/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100],'8accessories':[8.1/100,9.2/100,8.3/100,9.0/100,9.1/100,8.4/100,9.7/100,8.5/100,8.9/100,8.8/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100,1/100]};constEND_TIME=newDate();console.log(`花费:${END_TIME.getTime()-START_TIME.getTime()}ms`);console.log([...RESULTS].join('\n'));其实通过对比代码中的差异就很容易理解了。生成成功后发布。如需项目指导,请pm联系。