// Erzeugt App-Icons aus assets/logo-full.png: npx electron scripts/make-icons.js // Der dunkle Hintergrund um das Emblem wird freigestellt (transparent), das Gesicht innerhalb der Kontur bleibt. const { app, nativeImage } = require('electron'); const fs = require('fs'); // Von den Bildrändern aus fluten: Pixel ähnlich der Hintergrundfarbe werden transparent, der Kantensaum (max. 3 px) // bekommt Transparenz aus seiner Helligkeit und wird gegen den Hintergrund "entmischt", damit kein dunkler Rand bleibt. function cutOut(img) { const { width: w, height: h } = img.getSize(); const src = img.toBitmap(); // BGRA const out = Buffer.from(src); const at = (x, y) => (y * w + x) * 4; const bgI = at(w >> 1, 1); const bg = [src[bgI + 2], src[bgI + 1], src[bgI]]; const seen = new Uint8Array(w * h); const q = []; for (let x = 0; x < w; x++) q.push([x, 0, 0], [x, h - 1, 0]); for (let y = 0; y < h; y++) q.push([0, y, 0], [w - 1, y, 0]); while (q.length) { const [x, y, depth] = q.pop(); if (x < 0 || y < 0 || x >= w || y >= h || seen[y * w + x]) continue; const i = at(x, y), r = src[i + 2], g = src[i + 1], b = src[i]; const lum = 0.299 * r + 0.587 * g + 0.114 * b; const bgLike = Math.hypot(r - bg[0], g - bg[1], b - bg[2]) < 34; if (!bgLike && (lum >= 215 || depth >= 3)) continue; seen[y * w + x] = 1; const a = bgLike ? 0 : Math.max(0, Math.min(1, (lum - 40) / 195)); const un = (v, c) => Math.max(0, Math.min(255, Math.round((v - (1 - a) * c) / a))); if (a <= 0) out.fill(0, i, i + 4); else { out[i + 2] = un(r, bg[0]); out[i + 1] = un(g, bg[1]); out[i] = un(b, bg[2]); out[i + 3] = Math.round(a * 255); } const nd = bgLike ? 0 : depth + 1; q.push([x + 1, y, nd], [x - 1, y, nd], [x, y + 1, nd], [x, y - 1, nd]); } return nativeImage.createFromBitmap(out, { width: w, height: h }); } app.whenReady().then(() => { const src = nativeImage.createFromPath('assets/logo-full.png'); const { width } = src.getSize(); const k = width / 1254; // Ausschnitt: Kopf mit Hut, ohne Schriftzug const head = cutOut(src.crop({ x: Math.round(282 * k), y: Math.round(172 * k), width: Math.round(706 * k), height: Math.round(706 * k) })); fs.writeFileSync('build/icon.png', head.resize({ width: 512, height: 512, quality: 'best' }).toPNG()); fs.writeFileSync('src/renderer/logo.png', head.resize({ width: 96, height: 96, quality: 'best' }).toPNG()); fs.writeFileSync('assets/icon.png', head.resize({ width: 256, height: 256, quality: 'best' }).toPNG()); app.quit(); });