| name | eduwill-banner |
| description | Use when creating banner images for Eduwill (에듀윌) or similar Korean education companies. Triggers on keywords like 에듀윌, 배너, banner, 교육 배너, 공인중개사, 합격, eduwill. Uses Replicate Nano Banana Pro (google/nano-banana-pro) with reference images for high-quality AI-generated marketing banners. Also applies when user provides reference banner images and wants similar style banners generated. |
Eduwill Banner Generator
Overview
Generate high-quality Korean education marketing banners using Replicate Nano Banana Pro (google/nano-banana-pro) with reference image style transfer. The key to quality output is uploading reference images via replicate.files.create() and passing the URL through image_input — not base64, not prompt-only.
When to Use
- User asks to create 에듀윌/Eduwill banners
- User provides reference banner images and wants similar style
- Korean education company marketing banner generation
- Any banner task mentioning 공인중개사, 합격, 교육 플랫폼
When NOT to use: Simple text-only banners without reference images (use satori/sharp instead).
Brand Reference
eduwill_colors:
yellow: "#FCC300"
navy: "#111E50"
sky_blue: "#55ACE2"
red: "#F24646"
cta_red: "#F63B28"
text: "#222222"
eduwill_fonts:
primary: "Noto Sans KR"
web_ui: "Spoqa Han Sans Neo"
Core Workflow
digraph banner {
"Reference image exists?" [shape=diamond];
"Upload via replicate.files.create()" [shape=box];
"Create prediction with image_input" [shape=box];
"Poll until succeeded" [shape=box];
"Download result" [shape=box];
"Optional: composite text with sharp/canvas/pillow" [shape=box];
"Reference image exists?" -> "Upload via replicate.files.create()" [label="yes"];
"Reference image exists?" -> "Prompt-only generation" [label="no (lower quality)"];
"Upload via replicate.files.create()" -> "Create prediction with image_input";
"Create prediction with image_input" -> "Poll until succeeded";
"Poll until succeeded" -> "Download result";
"Download result" -> "Optional: composite text with sharp/canvas/pillow";
}
Quick Reference
| Parameter | Value | Notes |
|---|
| Model ID | google/nano-banana-pro | NOT nanonobandana/... |
aspect_ratio | "16:9" | Standard banner. Default is "match_input_image" when image_input provided |
resolution | "2K" | High quality |
output_format | "png" | Lossless |
image_input | [uploaded_url] | Must be real URL from replicate.files.create(), not base64. Supports up to 14 images |
safety_filter_level | "block_only_high" | Most permissive. Options: block_low_and_above, block_medium_and_above, block_only_high |
allow_fallback_model | false | Falls back to bytedance/seedream-5 if true and model is at capacity |
Implementation
Step 1: Upload Reference Image (Critical)
import Replicate from "replicate";
import fs from "fs";
import "dotenv/config";
const replicate = new Replicate({ auth: process.env.REPLICATE_API_TOKEN });
const buf = fs.readFileSync("inputs/reference-banner.png");
const file = await replicate.files.create(buf, {
filename: "reference.png",
content_type: "image/png",
});
const fileUrl = file.urls?.get || file.url;
Step 2: Generate with Polling (High Demand Resilience)
const pred = await replicate.predictions.create({
model: "google/nano-banana-pro",
input: {
prompt:
"Recreate this Korean education banner in the same style and layout. [specific details about what to keep/change]",
image_input: [fileUrl],
aspect_ratio: "16:9",
resolution: "2K",
output_format: "png",
safety_filter_level: "block_only_high",
},
});
let p = pred;
while (
p.status !== "succeeded" &&
p.status !== "failed" &&
p.status !== "canceled"
) {
await new Promise((r) => setTimeout(r, 5000));
p = await replicate.predictions.get(pred.id);
}
if (p.status === "succeeded") {
const url = typeof p.output === "string" ? p.output : p.output?.[0];
const resp = await fetch(url);
fs.writeFileSync("output/banner.png", Buffer.from(await resp.arrayBuffer()));
}
Step 3: Retry on High Demand (E003)
async function generateWithRetry(input, output, retries = 5) {
for (let i = 0; i < retries; i++) {
try {
const pred = await replicate.predictions.create({
model: "google/nano-banana-pro",
input,
});
let p = pred;
while (!["succeeded", "failed", "canceled"].includes(p.status)) {
await new Promise((r) => setTimeout(r, 5000));
p = await replicate.predictions.get(pred.id);
}
if (p.status === "succeeded") {
const url = typeof p.output === "string" ? p.output : p.output?.[0];
const resp = await fetch(url);
fs.writeFileSync(output, Buffer.from(await resp.arrayBuffer()));
return output;
}
throw new Error(p.error);
} catch (e) {
console.log(`Attempt ${i + 1} failed: ${e.message.substring(0, 60)}`);
if (i < retries - 1) await new Promise((r) => setTimeout(r, 15000));
}
}
return null;
}
Prompt Engineering for Eduwill Banners
Always start with: "Recreate this Korean education banner in the same style and layout."
Then specify what to keep/change:
| Banner Type | Prompt Pattern |
|---|
| 프로모션 (옐로우) | "...bright yellow gradient, study book on right, bold text on left, price tag" |
| 수상/1위 (골드) | "...dark gold gradient, sparkle confetti, golden trophy, award celebration" |
| 강사진 (베이지) | "...cream beige background, professional instructors in suits, CTA button" |
| 설명회 (다크) | "...dark charcoal background, LIVE badge, instructors on right, yellow CTA" |
| 캐릭터 (화이트) | "...white background, 3D cartoon students, speech bubbles, yellow bar at bottom" |
| 인포그래픽 | "...split layout, comparison cards, icons (brain/lightbulb/clock), clean infographic" |
Post-Processing with Other Methods
After AI generation, composite text overlays using:
- sharp: SVG text overlay + resize →
sharp(aiImage).composite([{input: svgBuffer}]).toFile()
- canvas:
loadImage(aiImage) → ctx.drawImage() → draw text/shapes on top
- pillow:
Image.open(aiImage) → ImageDraw text + gradient overlay
- html-to-image: AI image as
background:url(data:image/png;base64,...) in HTML template
- satori: AI image as
<img> in JSX tree, text elements overlaid
Common Mistakes
| Mistake | Fix |
|---|
Using replicate.run() | Use predictions.create() + polling — more resilient to E003 |
Passing base64 to image_input | Upload via replicate.files.create() first, pass real URL |
Wrong model ID nanonobandana/... | Correct: google/nano-banana-pro |
| Prompt-only without reference | Always provide image_input with reference for quality |
| No retry logic | E003 (high demand) is frequent — always retry 3-5 times with 15s delay |
Using 1K resolution | Use 2K for marketing-quality banners |
Prerequisites
npm install replicate dotenv
Project Structure
banner-generator/
├── .env # REPLICATE_API_TOKEN
├── inputs/ # Reference banner images
├── output/ # Generated banners
├── fonts/
│ ├── NotoSansKR-Bold.ttf
│ └── NotoSansKR-Regular.ttf
└── src/
└── replicate/
└── generate.js # Core generation module