Files
troxler-skat/card-game/svg_to_png.js
2026-05-31 14:39:45 -05:00

66 lines
2.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/* ============================================================
TROX SVG -> PNG Konverter für The Game Crafter
------------------------------------------------------------
TGC akzeptiert nur PNG/JPG bei 300 DPI in RGB (kein SVG, kein CMYK).
Rendert jede SVG exakt auf ihre width/height-Pixelgröße (= 300 DPI)
und gibt flaches RGB aus.
Voraussetzung (einmalig): npm install sharp
Verwendung:
node svg_to_png.js karten_export_tgc
node svg_to_png.js box_export
node svg_to_png.js scorepad_export
============================================================ */
const fs = require('fs');
const path = require('path');
let sharp;
try { sharp = require('sharp'); }
catch (e) {
console.error('Fehlendes Modul "sharp". Bitte zuerst ausführen:\n npm install sharp\n');
process.exit(1);
}
const srcDir = process.argv[2];
if (!srcDir || !fs.existsSync(srcDir)) {
console.error('Bitte gültigen Quellordner angeben, z.B.:\n node svg_to_png.js karten_export_tgc');
process.exit(1);
}
const outDir = `${srcDir.replace(/\/$/, '')}_png`;
if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });
const files = fs.readdirSync(srcDir).filter(f => f.toLowerCase().endsWith('.svg'));
if (!files.length) { console.error('Keine SVG-Dateien gefunden in', srcDir); process.exit(1); }
function readSize(svg) {
const wm = svg.match(/<svg[^>]*\bwidth="(\d+(?:\.\d+)?)"/);
const hm = svg.match(/<svg[^>]*\bheight="(\d+(?:\.\d+)?)"/);
if (wm && hm) return { w: Math.round(+wm[1]), h: Math.round(+hm[1]) };
const vb = svg.match(/viewBox="0 0 (\d+(?:\.\d+)?) (\d+(?:\.\d+)?)"/);
if (vb) return { w: Math.round(+vb[1]), h: Math.round(+vb[2]) };
return null;
}
console.log(`Konvertiere ${files.length} SVG -> PNG (${srcDir} -> ${outDir}) ...`);
(async () => {
for (const f of files) {
const svg = fs.readFileSync(path.join(srcDir, f), 'utf8');
const size = readSize(svg);
const outPath = path.join(outDir, f.replace(/\.svg$/i, '.png'));
let img = sharp(Buffer.from(svg), { density: 300 });
if (size) img = img.resize(size.w, size.h, { fit: 'fill' });
await img
.flatten({ background: '#ffffff' })
.png({ compressionLevel: 9 })
.toFile(outPath);
}
console.log(`Fertig. PNGs liegen in ${outDir} (RGB, exakte 300-DPI-Pixelmaße).`);
})();