Files
drawlogo/scripts/gen-avatars-png.js

73 lines
2.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 🖼️ 14 风格 × 100 = 1400 个 透明底 PNG 渲染脚本(512×512)
* 读取 output/agent-avatars-png/avatars/{style}/{file}.svg,
* Chrome headless 截图 → 透明背景 PNG(SVG 自带圆底,外部透明)。
*
* 用法:node scripts/gen-avatars-png.js
*/
'use strict';
const fs = require('fs');
const path = require('path');
const { spawn } = require('child_process');
const ROOT = path.resolve(__dirname, '..');
const SVG_ROOT = path.join(ROOT, 'output', 'agent-avatars-png', 'avatars');
const TMP_DIR = path.join(ROOT, 'output', '.tmp-av');
const CHROME = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe';
const SIZE = 512;
// —— 1. 收集全部 SVG 文件 ——
const files = [];
for (const dir of fs.readdirSync(SVG_ROOT, { withFileTypes: true })) {
if (!dir.isDirectory()) continue;
for (const f of fs.readdirSync(path.join(SVG_ROOT, dir.name))) {
if (f.endsWith('.svg')) files.push(path.join(dir.name, f));
}
}
files.sort();
console.log('📦 待渲染 SVG:' + files.length + ' 个');
// —— 2. 生成 HTML(透明背景 + SVG 居中,放大到 SIZE)——
fs.mkdirSync(TMP_DIR, { recursive: true });
const jobs = files.map((rel, i) => {
const svg = fs.readFileSync(path.join(SVG_ROOT, rel), 'utf8');
const html = `<!DOCTYPE html><html><head><meta charset="utf-8">
<style>html,body{margin:0;padding:0;width:${SIZE}px;height:${SIZE}px;overflow:hidden;background:transparent}
.wrap{width:${SIZE}px;height:${SIZE}px;display:flex;align-items:center;justify-content:center}</style>
</head><body><div class="wrap">${svg.replace('<svg ', '<svg width="' + SIZE + '" height="' + SIZE + '" ')}</div></body></html>`;
const hf = path.join(TMP_DIR, 'a' + i + '.html');
fs.writeFileSync(hf, html, 'utf8');
return { hf, out: path.join(SVG_ROOT, rel.replace(/\.svg$/, '.png')) };
});
// —— 3. 并发截图(透明底)——
function shot(job) {
return new Promise((res) => {
const p = spawn(CHROME, [
'--headless=new', '--disable-gpu', '--hide-scrollbars',
'--default-background-color=00000000',
'--force-device-scale-factor=1',
'--window-size=' + SIZE + ',' + SIZE, '--virtual-time-budget=600',
'--screenshot=' + job.out,
'file:///' + job.hf.replace(/\\/g, '/')
], { stdio: 'ignore' });
p.on('close', () => res());
p.on('error', () => res());
});
}
(async () => {
let done = 0, t0 = Date.now();
const CONC = 8;
for (let s = 0; s < jobs.length; s += CONC) {
const batch = jobs.slice(s, s + CONC);
await Promise.all(batch.map(shot));
done += batch.length;
if (done % 200 === 0 || done === jobs.length) {
console.log(`⏳ ${done}/${jobs.length} ${((Date.now() - t0) / 1000).toFixed(1)}s`);
}
}
fs.rmSync(TMP_DIR, { recursive: true, force: true });
console.log('🎉 完成 → 透明底 PNG(512×512),与 SVG 同目录');
})();