diff --git a/assets/icon.png b/assets/icon.png index 57d9198..a0222cd 100644 Binary files a/assets/icon.png and b/assets/icon.png differ diff --git a/build/icon.png b/build/icon.png index 9fca416..c2d6fb3 100644 Binary files a/build/icon.png and b/build/icon.png differ diff --git a/scripts/make-icons.js b/scripts/make-icons.js index f4e093c..21c2bf9 100644 --- a/scripts/make-icons.js +++ b/scripts/make-icons.js @@ -1,12 +1,45 @@ // 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 = src.crop({ x: Math.round(282 * k), y: Math.round(172 * k), width: Math.round(706 * k), height: Math.round(706 * k) }); + 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()); diff --git a/src/renderer/logo.png b/src/renderer/logo.png index 858cf96..9d6f172 100644 Binary files a/src/renderer/logo.png and b/src/renderer/logo.png differ