generate-icons.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. const fs = require('fs');
  2. const path = require('path');
  3. let sharp;
  4. try {
  5. sharp = require('sharp');
  6. } catch (error) {
  7. console.error('Missing dependency: sharp. Run pnpm install first.');
  8. process.exit(1);
  9. }
  10. const appSvgPath = path.join(__dirname, '../public/favicon.svg');
  11. const traySvgPath = path.join(__dirname, '../public/tray-icon.svg');
  12. const iconsDir = path.join(__dirname, '../public/icons');
  13. const buildDir = path.join(__dirname, '../build');
  14. const docsDir = path.join(__dirname, '../../docs');
  15. const iconSizes = [16, 24, 32, 48, 64, 128, 256, 512];
  16. const trayIcons = [
  17. { name: 'tray-icon.png', size: 32 },
  18. { name: 'tray-icon@2x.png', size: 64 },
  19. ];
  20. async function renderPng(sourceBuffer, targetPath, size) {
  21. await sharp(sourceBuffer)
  22. .resize(size, size, {
  23. fit: 'contain',
  24. kernel: sharp.kernel.lanczos3,
  25. })
  26. .png({
  27. compressionLevel: 9,
  28. adaptiveFiltering: true,
  29. palette: size <= 64,
  30. })
  31. .toFile(targetPath);
  32. }
  33. async function generateIcons() {
  34. if (!fs.existsSync(appSvgPath)) {
  35. throw new Error(`App icon SVG not found: ${appSvgPath}`);
  36. }
  37. if (!fs.existsSync(traySvgPath)) {
  38. throw new Error(`Tray icon SVG not found: ${traySvgPath}`);
  39. }
  40. fs.mkdirSync(iconsDir, { recursive: true });
  41. fs.mkdirSync(buildDir, { recursive: true });
  42. fs.mkdirSync(docsDir, { recursive: true });
  43. const appSvg = fs.readFileSync(appSvgPath);
  44. const traySvg = fs.readFileSync(traySvgPath);
  45. for (const size of iconSizes) {
  46. const target = path.join(iconsDir, `icon-${size}.png`);
  47. await renderPng(appSvg, target, size);
  48. console.log(`generated icon-${size}.png`);
  49. }
  50. for (const tray of trayIcons) {
  51. const target = path.join(iconsDir, tray.name);
  52. await renderPng(traySvg, target, tray.size);
  53. console.log(`generated ${tray.name}`);
  54. }
  55. const logoPath = path.join(iconsDir, 'logo.png');
  56. await renderPng(appSvg, logoPath, 512);
  57. fs.copyFileSync(path.join(iconsDir, 'icon-256.png'), path.join(buildDir, 'icon.png'));
  58. fs.copyFileSync(logoPath, path.join(docsDir, 'logo.png'));
  59. console.log('icon generation complete');
  60. }
  61. generateIcons().catch((error) => {
  62. console.error(error);
  63. process.exit(1);
  64. });