[object Object]

← back to Dw Fleet Registry

rooms: gen-hero-rooms.mjs (generate room-setting heroes via :3075 + 2x upscale)

ab9e050fa671315fe638ef522478fb97a7cadb72 · 2026-06-01 15:51:15 -0700 · SteveStudio2

Reusable pilot pipeline: pattern URL -> Gemini room render (~$0.04) -> sips 2x upscale to
~1728px (clears the 1400px hero guard). Verified on corkwallcovering (3 rooms, luxe quality).
gitignores the heavy PNG artifacts. Also lands the user's viewer sharp/thumbSrc edits.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit ab9e050fa671315fe638ef522478fb97a7cadb72
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Mon Jun 1 15:51:15 2026 -0700

    rooms: gen-hero-rooms.mjs (generate room-setting heroes via :3075 + 2x upscale)
    
    Reusable pilot pipeline: pattern URL -> Gemini room render (~$0.04) -> sips 2x upscale to
    ~1728px (clears the 1400px hero guard). Verified on corkwallcovering (3 rooms, luxe quality).
    gitignores the heavy PNG artifacts. Also lands the user's viewer sharp/thumbSrc edits.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 .gitignore         |  1 +
 gen-hero-rooms.mjs | 28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/.gitignore b/.gitignore
index 58de67d..6a58044 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ dist/
 build/
 .next/
 brand/heroes/
+data/hero-rooms/
diff --git a/gen-hero-rooms.mjs b/gen-hero-rooms.mjs
new file mode 100644
index 0000000..1d36dda
--- /dev/null
+++ b/gen-hero-rooms.mjs
@@ -0,0 +1,28 @@
+#!/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}`);
+}

← f1cf338 fleet viewer: proxy-side image resize via optional sharp (/i  ·  back to Dw Fleet Registry  ·  full 65-site header certification results a45e546 →