const path = require("path"); const fs = require("fs"); const gm = require("gm").subClass({ imageMagick: true }); const queue = require("queue"); const q = queue({ results: [], concurrency: 16 }); let main = { list: [], imgsrc: "", basePath: "/Users/drew/Downloads/未命名文件夹", total: 0, now: 0, max: 5000, type: 0, backName(list) { return [...list].map((item) => { return item.name; }); }, setList(name, list = [], keyIndex = 0, keyLength = 1) { let names = name.split("_"); let num = Math.ceil((Number(names[2]) * this.max) / 100); for (let i = 0; i < num; i++) { let index = this.getIndex(list, keyIndex, keyLength); list[index][keyIndex] = name; } return list; }, getIndex(list, keyIndex, keyLength) { let index = this.getRandom(0, this.max - 1); if (!list[index]) { list[index] = new Array(keyLength); } if (list[index][keyIndex]) { return this.getIndex(list, keyIndex, keyLength); } else { return index; } }, drawEnter() { if (!fs.existsSync(path.resolve(this.basePath, "images"))) { fs.mkdirSync(path.resolve(this.basePath, "images")); } let fileList = fs.readdirSync(this.basePath).filter((i) => { return !i.startsWith(".") && i.endsWith(".png"); }); let _map = new Map(); fileList.forEach((item) => { let names = item.split("_"); let _list = this.type ? [[], []] : []; if (_map.has(names[1])) { _list = _map.get(names[1]); } if (this.type) { if (Number(names[2]) > 0) { _list[1].push(item); } else { _list[0].push(item); } } else { _list.push(item); } _map.set(names[1], _list); }); if (this.type) { this.drawType2(_map); } else { this.drawType1(_map); } }, drawType2(_map) { const allkeys = [..._map.keys()].sort((a, b) => { return Number(a) - Number(b); }); let list1 = allkeys.map((item) => { return _map.get(item)[0]; }); let list2 = allkeys.map((item) => { return _map.get(item)[1]; }); let allList = new Array(this.max); list2.forEach((_list, index) => { _list.forEach((item) => { allList = this.setList(item, allList, index, allkeys.length); }); }); for (let i = 0; i < allList.length; i++) { let _list1 = allList[i] || new Array(allkeys.length); list1.forEach((_list, index) => { if (!_list1[index]) { if (_list.length !== 0) { _list1[index] = _list[this.getRandom(0, _list.length - 1)]; } else { _list1[index] = list2[index][ this.getRandom(0, list2[index].length - 1) ]; } } }); } this.total = allList.length; this.startDraw(allList); }, drawType1(_map) { [..._map.keys()].forEach((_key) => { let _list = _map.get(_key); let _radios2 = []; let _radios = _list.map((item) => { let names = item.split("_"); let num = Number(names[2]); if (num > 0) { _radios2.push(num); } return num; }); let allNums = _radios2.reduce((pre, cur) => { return pre + cur; }, 0); let before = 0; let _num = []; let _listMap = new Map(); _radios.forEach((item, index) => { let __num = before; if (item > 0) { __num += item; } else { __num += Math.ceil( (100 - allNums) / (_radios.length - _radios2.length) ); } before = __num; _num.push(__num); _listMap.set(_list[index], __num); }); _map.set(_key, _listMap); }); let allList = [..._map.keys()] .sort((a, b) => { return Number(a) - Number(b); }) .map((_key) => { return _map.get(_key); }); let totalList = []; for (let i = 0; i < this.max; i++) { let _list = []; let rs = []; allList.forEach((_vals) => { let vals = [..._vals.values()]; let r = this.getRandom(1, vals[vals.length - 1]); let index = vals.findIndex((item) => { return r <= item; }); rs.push(r); _list.push([..._vals.keys()][index]); }); totalList.push(_list); } this.startDraw(totalList); }, startDraw(list) { let c = 0; for (let imgs of list) { q.push((cb) => { let t = new Date().getTime(); let name = imgs .map((item) => { let infos = item.replace(/.png/, "").split("_"); return infos[infos.length - 1]; }) .join("_") + ".png"; let g = gm(); for (let img of imgs) { g = g.in(path.resolve(this.basePath, img)); } g.mosaic().write( path.resolve(this.basePath, "images", name), function (err) { if (err) { console.log(err); } console.log( ++c + " done in " + (new Date().getTime() - t) + "ms" ); cb(); } ); }); } }, getRandom(m = 1, n = 100) { return Math.round(Math.random() * (n - m) + m); }, }; main.drawEnter(); let t = new Date().getTime(); q.start(function (err) { if (err) throw err; console.log( "all done in " + parseInt((new Date().getTime() - t) / 1000) + "s" ); });