Inspiration
Every marketing team we know ships one hero image and then crops it to death. The desktop banner gets squeezed into a 1584x396 LinkedIn header, the product slides out of frame, and the headline lands on top of the thing it's supposed to be selling. Cloudinary, imgix and every DAM on the market solve this by cropping one image N ways, which is exactly why a desktop hero looks wrong on a phone. A single composition cannot serve every aspect ratio. It never could.
The other half of the frustration is cost. Brand teams commission agencies for 3D product renders and brand libraries, then those assets are locked to the exact canvas they were built for. Change the breakpoint and you're back in the queue.
So we asked a different question. What if the brand look were the durable asset, and the composition were generated per canvas? Not cropped down to it. Composed for it.
Compose, don't crop. That's the whole thesis.
Testing credentials
-Email: tlotliso.morethi+judges@gmail.com -Password: Genblaze
What it does
PEG locks a brand's look once, then generates a differently composed key visual for every breakpoint you need.
A team uploads their brand kit a single time: up to three style references that teach palette, lighting, materials and mood, plus their approved logos. PEG quantizes the references and extracts a six colour palette automatically, then injects the brand name and those exact hex values into every prompt server side, at the protected service boundary rather than on the canvas, so no user can generate outside the brand lock.
From there, a campaign brief on a node canvas produces a plate. That plate then fans out to as many breakpoints as you want. Each one gets its own Format spec: exact dimensions, a safe area kept calm for headline copy, and a focal point for where the subject should sit. A 1920x600 web hero puts the subject right of centre with the left third clear. A 1080x1920 story stacks it with room up top. Same brand, same lighting, same palette, composed for each canvas.
Approved assets stay approved. Logos and real app screenshots are composited from the originals, never regenerated, because "very close" is a brand failure when a legal team signs off pixel exact artwork.
Every published asset carries a provenance manifest written to Backblaze B2 recording which model produced it from which references, and PEG verifies that manifest before calling the run done.
We demoed it on TaxiFlex, a South African minibus taxi routing app, going from a folder of brand assets to a web hero, a LinkedIn banner, a story and an App Store screenshot in one pass.
How we built it
Next.js 16 and React 19 on the front end, with a custom node canvas built from scratch: nodes, typed ports, edge dragging, zoom, selection, and dependency ordered execution. The graph is a DAG, and independent branches are deliberately isolated, so a failed mobile branch never takes its desktop sibling down with it.
The backend is a FastAPI service running Genblaze, deployed separately because Genblaze is Python only and a run takes minutes, well past any serverless timeout. Two services on Render, wired through a shared token, with the Next.js route handlers proxying through.
Backblaze B2 is the spine. Brand assets, every generated plate, and every provenance manifest live there, workspace scoped by key prefix, served to the browser through presigned URLs.
Generation runs on Gemini 3.1 Flash Lite Image through GMI. Compositing and breakpoint geometry are deterministic local operations in Pillow, not model calls, because geometry should not be probabilistic.
Challenges we ran into
Image models ignore the size you ask for. None of the models available to us honour resolution parameters in any reliable way. Asking for 1920x600 gets you something roughly that shape when it feels like it. That's fatal for a product whose entire pitch is exact breakpoints. Our fix was to stop asking: PEG builds a canvas at exactly the target size, seats the existing plate in the content zone opposite the safe band, generates a feathered mask over everything else, and outpaints into it. The dimensions are then exact by construction because we made them, not because a model agreed to.
We were wrong about what models can render. Our own architecture notes said, in bold, that diffusion cannot render your product and not to try. Then we tested it. Gemini 3.1 Flash Lite Image renders exact wordmarks, correctly spelled and crisp, including inside reflections. We had to go back and rewrite the rule. The accurate version is narrower: a model cannot conjure a brand asset it has never seen, but it handles one you specify or supply. That reversal opened up a whole generated lane (product in reflection, at an angle, relit to match the plate) that a flat PNG composite can never do.
The model matrix moved under us. The two models we designed reference conditioning around both disappeared mid build: one went dead upstream, the other turned out to be entitlement gated. Some Bria endpoints dropped roughly two submits in three. We stopped trusting any single model and exposed a model picker on the node itself so a swap doesn't require a deploy.
Eventual consistency nearly broke provenance. B2 can return a stale read immediately after a write, which made freshly written manifests fail verification. A provenance feature that reports "unverified" for assets that are perfectly fine is worse than having no provenance at all, so verification retries and tolerates the read-after-write window instead of reporting a false negative.
Free tier networking. Render's service linking gave us no reachable address on the free tier, so we tested both approaches against a live deploy, recorded exactly what each one returned, and pinned the public hostname explicitly with token auth in front of it. We also shipped a health endpoint that reports the resolved service address and whether the upstream answers, because a misconfigured URL and a dead service look identical from the app.
Our own canvas fought us. Dragging between ports never actually created a connection, and the pan gesture on the canvas root was swallowing pointer events from dialogs rendered inside it, so buttons silently did nothing. Both were the kind of bug that makes a demo look broken when the pipeline underneath is fine.
Accomplishments that we're proud of
The breakpoint fan-out works, and it is genuinely composition rather than cropping. One plate, several canvases, each with its subject placed correctly and its headline space intact. The geometry is deterministic, so it produces the same result every time.
The brand lock is enforced server side, not suggested client side. Uploading a kit once means every generation in that workspace inherits the same labelled references and the same palette, with explicit instructions to strip branding that leaked in from source references. It's a real constraint, not a prompt suggestion.
Provenance ships with every asset and verifies. For the corporate brand teams this is aimed at, "which model made this, from what, and can you prove it" is not a nice to have.
And we killed a bold, confident, wrong assumption in our own design docs by testing it. The architecture is better for it.
What we learned
Put the non-negotiable geometry in code and the taste in the model. Every problem we had came from asking a model to do something deterministic. Every fix came from taking that job back and giving the model the job it's actually good at.
Constrain generation at the boundary, not the interface. Moving the brand lock into the protected service made it something we could reason about, rather than something a user could edit away.
Test the assumption you're most confident about. Ours was in bold in our own docs and it was wrong.
And build the diagnosis path early. The health endpoint took twenty minutes and saved hours, because on a free tier with cold starts, everything looks like the same failure until you can tell the difference.
What's next for PEG
Finish the composite lane. The local compositor runs today for App Store layouts, placing an authentic screenshot into a device frame with approved logo and copy. Generalising that to arbitrary product cutouts on any plate is the next piece.
Derive the look in words. The palette is extracted automatically, but the description of the look is not. A Read Style node that reads the style references and writes that description would close the last manual gap in the brand lock.
Two dimensional focal points. Safe areas are currently thirds. A centred safe region has no single rectangular complement, so it falls back to prompt only. Real focal point coordinates would fix that and unlock formats we skip today.
Motion. The video and audio nodes are in the catalog and held back on cost and validation time. A key visual that animates for the same campaign, from the same brand lock, is the obvious next surface.
Ship it as a product. This was built for a hackathon, but the spend it attacks is real, and nobody we've shown it to has said the crop problem isn't a problem.

Log in or sign up for Devpost to join the conversation.