← back to Dw Fleet Registry

gen-hero-rooms.mjs

29 lines

#!/usr/bin/env node
// Generate room-setting hero images from a wallpaper pattern via the DW room-setting
// service (:3075, Gemini 2.5 Flash Image), then 2x-upscale to clear the 1400px hero guard.
//   node gen-hero-rooms.mjs <patternUrl> <outDir> [living_room office dining_room bedroom]
// Cost: ~$0.04/room (paid Gemini). Output: <outDir>/<room>-<angle>.png (~1728px long edge).
import fs from 'node:fs';
import { execFileSync } from 'node:child_process';
const [patternUrl, outDir, ...roomsArg] = process.argv.slice(2);
if (!patternUrl || !outDir) { console.error('usage: gen-hero-rooms.mjs <patternUrl> <outDir> [rooms...]'); process.exit(1); }
const ROOMS = (roomsArg.length ? roomsArg : ['living_room','office','dining_room']).map(r => {
  const m = { living_room:'straight_on', office:'angled_left', dining_room:'straight_on', bedroom:'straight_on', bathroom:'angled_right' };
  return { roomType: r, angle: m[r] || 'straight_on', cameraDistance: r==='bedroom'?5:(r==='living_room'?8:11) };
});
const buf = Buffer.from(await (await fetch(patternUrl)).arrayBuffer());
const b64 = buf.toString('base64');
fs.mkdirSync(outDir, { recursive: true });
for (const j of ROOMS) {
  const t0 = Date.now();
  const r = await fetch('http://45.61.58.125:3075/api/generate-room', { method:'POST', headers:{'Content-Type':'application/json'},
    body: JSON.stringify({ patternBase64:b64, roomType:j.roomType, angle:j.angle, cameraDistance:j.cameraDistance, patternWidth:36, patternHeight:36 }) });
  const d = await r.json().catch(()=>({}));
  if (d.success && d.image) {
    const out = `${outDir}/${j.roomType}-${j.angle}.png`;
    fs.writeFileSync(out, Buffer.from(d.image.replace(/^data:[^,]+,/,''), 'base64'));
    try { execFileSync('sips', ['-Z','2368', out]); } catch {}
    console.log(`OK ${j.roomType}/${j.angle} -> ${out} ${Math.round(fs.statSync(out).size/1024)}KB ${((Date.now()-t0)/1000).toFixed(1)}s`);
  } else console.log(`FAIL ${j.roomType}: ${d.error||r.status}`);
}