// 生成 Linux 多尺寸图标集 -> resources/icons/x.png // // 为什么需要多尺寸: electron-builder 的 Linux 打包会把图标装进 // /usr/share/icons/hicolor/x/apps/.png。 // 如果 linux.icon 指向"单张 PNG", app-builder 解析不出尺寸 (返回 size=0), // 图标就被装到 hicolor/0x0/ 这种非法目录里, 桌面环境根本找不到 -> 安装后没图标。 // 指向一个"目录 + x.png 命名"才能被正确识别。 // // 用法: // node scripts/make-icon.js # 用 resources/icon.png 作为基准图 // node scripts/make-icon.js <源图路径> # 用指定图片重新生成基准图 + 全套尺寸 // // 依赖: ImageMagick 的 convert (生成结果已提交, 平时不需要跑这个脚本) const { execFileSync } = require('node:child_process') const fs = require('node:fs') const path = require('node:path') const RES = path.resolve(__dirname, '..', 'resources') const OUT_DIR = path.join(RES, 'icons') const BASE = path.join(RES, 'icon.png') // hicolor 标准尺寸: 覆盖所有实际显示场景, 全部从 512 基准图缩小而来 (清晰不糊) const SIZES = [16, 24, 32, 48, 64, 128, 256, 512] function haveConvert() { try { execFileSync('convert', ['-version'], { stdio: 'ignore' }) return true } catch { return false } } function convert(args) { execFileSync('convert', args, { stdio: 'inherit' }) } function main() { if (!haveConvert()) { console.error('需要 ImageMagick 的 convert 命令。') console.error('Debian/Ubuntu: sudo apt install imagemagick') process.exit(1) } const src = process.argv[2] if (src) { // 指定了源图: 先把基准图做成 512x512 (最高精度, 往下缩都清晰) if (!fs.existsSync(src)) { console.error('源图不存在:', src) process.exit(1) } convert([src, '-resize', '512x512', '-background', 'none', '-gravity', 'center', '-extent', '512x512', BASE]) console.log('基准图已更新:', BASE) } if (!fs.existsSync(BASE)) { console.error('基准图不存在:', BASE) process.exit(1) } fs.mkdirSync(OUT_DIR, { recursive: true }) for (const s of SIZES) { const out = path.join(OUT_DIR, `${s}x${s}.png`) // <= 基准尺寸的直接从基准图降采样 (只重采样一次, 小图标才清晰); // 超过基准尺寸的才放大, 放到最后单独处理 if (s <= 256) { convert([BASE, '-resize', `${s}x${s}`, '-strip', out]) } else { convert([BASE, '-resize', '512x512', '-background', 'none', '-gravity', 'center', '-extent', '512x512', out]) } console.log('生成', path.relative(process.cwd(), out)) } console.log('\n完成。打包时用 linux.icon = "resources/icons" 指向这个目录。') } main()