96 lines
3.3 KiB
JavaScript
96 lines
3.3 KiB
JavaScript
import sharp from "sharp";
|
|
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { execSync } from "node:child_process";
|
|
|
|
const INPUT_PATH = "C:\\Users\\bognar\\.gemini\\antigravity\\brain\\79536897-1e16-48e6-8287-37f8f8fa042d\\logo_conversion_result_ca9d_1774554931035.png";
|
|
const PUBLIC_DIR = "public/images";
|
|
const FAVICON_PATH = "app/favicon.ico";
|
|
|
|
async function main() {
|
|
console.log("Processing logo from high-res screenshot...");
|
|
|
|
// 1. Load and process the main logo
|
|
// The screenshot is white logo on a presumably white canvas (or blue bg was invisible)
|
|
// We'll trim to the bounding box of the non-empty part
|
|
const image = sharp(INPUT_PATH);
|
|
|
|
// To deal with potential background, we'll trim first
|
|
// We assume the background is white #FFFFFF or very close
|
|
const trimmed = await image
|
|
.trim({ threshold: 40 }) // Tight trim
|
|
.toBuffer();
|
|
|
|
// Now make it transparent
|
|
// We'll use a mask based on the white color
|
|
// Since it's golden, it shouldn't contain pure white except maybe in reflections
|
|
// But we want the background (pure white) to be transparent
|
|
const finalLogo = sharp(trimmed)
|
|
.ensureAlpha()
|
|
.raw()
|
|
.toBuffer({ resolveWithObject: true });
|
|
|
|
const { data, info } = await finalLogo;
|
|
|
|
// Simple color-to-alpha: if a pixel is white, set alpha to 0
|
|
const threshold = 250; // Very close to white
|
|
for (let i = 0; i < data.length; i += 4) {
|
|
const r = data[i];
|
|
const g = data[i + 1];
|
|
const b = data[i + 2];
|
|
if (r > threshold && g > threshold && b > threshold) {
|
|
data[i + 3] = 0; // Transparent
|
|
}
|
|
}
|
|
|
|
const finalImage = sharp(data, {
|
|
raw: {
|
|
width: info.width,
|
|
height: info.height,
|
|
channels: 4,
|
|
},
|
|
});
|
|
|
|
// Scale down to a reasonable size for the website if it's too big
|
|
// The original was 215x78. Let's make it 645 (3x) for high-res
|
|
const targetWidth = 645;
|
|
await finalImage
|
|
.resize(targetWidth, null, { withoutEnlargement: true })
|
|
.png()
|
|
.toFile(path.join(PUBLIC_DIR, "logo-white.png"));
|
|
|
|
console.log("Saved logo-white.png");
|
|
|
|
// 2. SVG wrappers
|
|
const finalMeta = await sharp(path.join(PUBLIC_DIR, "logo-white.png")).metadata();
|
|
const logoData = (await fs.readFile(path.join(PUBLIC_DIR, "logo-white.png"))).toString("base64");
|
|
const svgWrapper = `<svg width="${finalMeta.width}" height="${finalMeta.height}" viewBox="0 0 ${finalMeta.width} ${finalMeta.height}" xmlns="http://www.w3.org/2000/svg">
|
|
<image href="data:image/png;base64,${logoData}" width="${finalMeta.width}" height="${finalMeta.height}" />
|
|
</svg>`;
|
|
|
|
await fs.writeFile(path.join(PUBLIC_DIR, "logo-white.svg"), svgWrapper);
|
|
await fs.writeFile(path.join(PUBLIC_DIR, "logo-dark.svg"), svgWrapper);
|
|
console.log("Saved logo-white.svg and logo-dark.svg");
|
|
|
|
// 3. Favicon
|
|
console.log("Generating favicon...");
|
|
const squareSize = 64;
|
|
await finalImage
|
|
.resize(squareSize, squareSize, { fit: "contain", background: { r: 0, g: 0, b: 0, alpha: 0 } })
|
|
.png()
|
|
.toFile("temp-favicon.png");
|
|
|
|
try {
|
|
execSync("npx -y png-to-ico temp-favicon.png > " + FAVICON_PATH, { shell: true });
|
|
console.log("Saved favicon.ico");
|
|
} catch (err) {
|
|
await fs.copyFile("temp-favicon.png", FAVICON_PATH);
|
|
} finally {
|
|
try { await fs.unlink("temp-favicon.png"); } catch {}
|
|
}
|
|
|
|
console.log("All assets updated.");
|
|
}
|
|
|
|
main().catch(console.error);
|