card game

This commit is contained in:
2026-05-31 14:39:45 -05:00
parent 5cc62433bd
commit 6abe253547
18 changed files with 2713 additions and 20 deletions

65
card-game/svg_to_png.js Normal file
View File

@@ -0,0 +1,65 @@
#!/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).`);
})();