diff --git a/server/index.ts b/server/index.ts index 4caf8bc..1c7f369 100644 --- a/server/index.ts +++ b/server/index.ts @@ -7,6 +7,7 @@ */ import { resolve } from "node:path"; +import sharp from "sharp"; import { Hono } from "hono"; import { cors } from "hono/cors"; import type { ServerWebSocket } from "bun"; @@ -738,22 +739,27 @@ async function process3DGenJob(job: Gen3DJob) { const MODEL = "fal-ai/hunyuan3d-v21"; try { - // 1. Read staged image from disk and convert to data URI for reliable fal.ai delivery + // 1. Resize staged image with sharp (max 1024px) for reliable fal.ai processing let imageInput = job.imageUrl; const stagedMatch = job.imageUrl.match(/\/(?:api\/files|data\/files)\/generated\/([^?#]+)/); if (stagedMatch) { try { const dir = resolve(process.env.FILES_DIR || "./data/files", "generated"); - const file = Bun.file(resolve(dir, stagedMatch[1])); + const srcPath = resolve(dir, stagedMatch[1]); + const file = Bun.file(srcPath); if (await file.exists()) { - const buf = Buffer.from(await file.arrayBuffer()); - const ext = stagedMatch[1].split(".").pop()?.toLowerCase() || "jpg"; - const mime = ext === "png" ? "image/png" : ext === "webp" ? "image/webp" : "image/jpeg"; - imageInput = `data:${mime};base64,${buf.toString("base64")}`; - console.log(`[3d-gen] Using data URI (${Math.round(buf.length / 1024)}KB) instead of URL`); + const resizedBuf = await sharp(srcPath) + .resize(1024, 1024, { fit: "inside", withoutEnlargement: true }) + .jpeg({ quality: 90 }) + .toBuffer(); + const resizedName = `stage-resized-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.jpg`; + await Bun.write(resolve(dir, resizedName), resizedBuf); + // Use public HTTPS URL for the resized image + imageInput = `${PUBLIC_ORIGIN}/api/files/generated/${resizedName}`; + console.log(`[3d-gen] Resized image: ${Math.round(resizedBuf.length / 1024)}KB → ${imageInput}`); } } catch (e: any) { - console.warn(`[3d-gen] Data URI fallback failed, using URL:`, e.message); + console.warn(`[3d-gen] Resize failed, using original URL:`, e.message); } }