From 358dd3eac033ec1e22634a6201867b3230783387 Mon Sep 17 00:00:00 2001 From: John Poole Date: Thu, 5 Mar 2026 12:49:09 -0800 Subject: [PATCH] Added webp image creation --- web/batch_glb_png/batch_render.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/web/batch_glb_png/batch_render.js b/web/batch_glb_png/batch_render.js index f5d2345..c494969 100644 --- a/web/batch_glb_png/batch_render.js +++ b/web/batch_glb_png/batch_render.js @@ -4,6 +4,9 @@ * 20260228 ChatGPT * $Header$ * + * This script takes a JSON job description and batch renders PNGs from GLBs + * using a headless browser and a local static server. + * * Example: * node batch_render.js job.json */ @@ -14,10 +17,12 @@ import process from 'node:process'; import http from 'node:http'; import { pathToFileURL, fileURLToPath } from 'node:url'; import puppeteer from 'puppeteer'; +import sharp from 'sharp'; function die (msg) { console.error(msg); process.exit(1); } function ensureDir(p) { fs.mkdirSync(p, { recursive: true }); } + function listFiles(dir, suffix) { const out = []; for (const ent of fs.readdirSync(dir, { withFileTypes: true })) { @@ -102,6 +107,8 @@ async function main() { const pattern = (job.pattern ?? ".glb").toLowerCase(); ensureDir(outputDirAbs); + const webpDirAbs = path.join(outputDirAbs, '../webp'); + ensureDir(webpDirAbs); const glbs = listFiles(inputDirAbs, pattern); if (glbs.length === 0) die(`No files ending with '${pattern}' found under ${inputDirAbs}`); @@ -166,9 +173,25 @@ async function main() { throw new Error(`No pngDataUrl produced for ${glbAbs} (status=${JSON.stringify(status)})`); } + //const b64 = status.pngDataUrl.replace(/^data:image\/png;base64,/, ''); + //fs.writeFileSync(outAbs, Buffer.from(b64, 'base64')); + //console.log(`WROTE\t${outAbs}`); const b64 = status.pngDataUrl.replace(/^data:image\/png;base64,/, ''); - fs.writeFileSync(outAbs, Buffer.from(b64, 'base64')); + const pngBuffer = Buffer.from(b64, 'base64'); + + /* write PNG */ + fs.writeFileSync(outAbs, pngBuffer); console.log(`WROTE\t${outAbs}`); + + /* write WEBP */ + const webpName = sanitizeBasename(glbAbs).replace(/\.glb$/i, '.webp'); + const webpAbs = path.join(webpDirAbs, webpName); + + await sharp(pngBuffer) + .webp({ quality: 92 }) + .toFile(webpAbs); + + console.log(`WROTE\t${webpAbs}`); } await page.close();