generate-icons.cjs 2.0 KB

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