Your Face on a World Cup Sticker: Our Nano Banana Story
DEV Community

Your Face on a World Cup Sticker: Our Nano Banana Story

The idea: putting our own faces on the stickers

The starting point was not a technical challenge. It was fun. We wanted the nostalgia of football sticker albums without simply reproducing a traditional player portrait. Each result had to feel personal:

  • The face should remain recognizable.
  • The rendering should look like a playful children's illustration, not a photorealistic edit.
  • The person should wear their selected national team's kit.
  • Every sticker should tell a small story.
  • Rare borders and special effects should bring back the excitement of opening a pack.

The experience is deliberately simple. You provide a photo and a name, choose your team, and let the application create the surprise. Behind that simple flow, the application runs an Astro frontend on Firebase Hosting and an API on Cloud Run. The browser sends the photo and the user's choices to the backend. The backend selects the scenario, builds the complete prompt, attaches the relevant references, and calls the Gemini image-generation API. The AI is asked to preserve the real identity cues visible in the photo - face shape, skin tone, hairstyle, facial hair, eyebrows, expression, and accessories such as glasses. At the same time, it must turn that identity into a simplified, expressive cartoon. This balance matters. Too realistic, and the result loses its friendly illustrated character. Too generic, and the person no longer recognizes themselves. The fun happens in between.

One prompt engine, dozens of scenarios

A prompt like β€œturn this person into a football sticker” can produce an image. It does not produce a consistent collection. To make stickers generated for different people feel as if they belong to the same album, we built every prompt from the same six-part structure:

  • Subject and identity - who the person is and which visible traits must be preserved.
  • Kit - the selected national team and its official football jersey.
  • Action - the humorous pose or celebration.
  • Environment - the stadium, pitch, city, or imaginary setting around the player.
  • Style and card layout - the shared visual rules, border, typography, and rarity effects.
  • Output constraints - a centered, vertical, full-bleed composition suitable for a sticker.

In the backend, those layers are assembled in TypeScript. Here is a shortened version of the production function:

function buildStickerPrompt(opts: PromptOptions): string {
  const name = (opts.userName || " PLAYER ").trim().toUpperCase();
  const border = opts.border ?? opts.scenario.border;
  const styleBible = opts.styleBible?.trim() || DEFAULT_STYLE_BIBLE;
  return [
    " Using the attached real photo as the identity reference... ",
    `The character wears the official kit of ${opts.teamName}.`,
    ...(opts.referenceInstruction?.trim() ? [opts.referenceInstruction.trim()] : []),
    `Scenario: the character is ${opts.scenario.action}.`,
    `Presented inside a trading-card layout with ${borderPhrase(border)}.`,
    `At the bottom, render the name '${name}' on one readable line.`,
    styleBible,
    " Center the subject. Use a vertical, full-bleed composition. ",
  ].join(" ");
}

The function keeps the permanent art direction in one place, then injects only the values that make a sticker unique. It also makes optional instructions explicit: a jersey reference, trophy, ball, or rare effect is included only when the selected slot needs it.

The scenarios provide variety. One person can perform a bicycle kick in a packed stadium. Another can ride a rocket-powered football through space, take a victory selfie, attempt a Panenka, meditate on the pitch, or lift the trophy under golden confetti.

Here is a shortened example based on the real prompt structure:

Using the attached real photo as the identity reference, transform this exact person into a humorous parodic cartoon caricature. Match their real face closely: face shape, skin tone, hairstyle, facial hair, eyebrows, and expression. The character is a professional soccer player wearing the official kit of the France national football team. Scenario: the character is performing a spectacular overhead bicycle kick in mid-air, with the ball blurring off the foot and a packed stadium behind. Presented inside a rectangular trading-card layout with a vibrant blue parallel border. At the top, arched text reads 'WORLD CUP 2026'. At the bottom, the name 'JULIEN' is fully readable. Art style: die-cut sticker design, bold clean white outer outline, 2D vector illustration, flat colors, simple cel shading, thick black ink outlines, high contrast, and playful humorous cartoon caricature. Center the subject. Use a vertical, full-bleed composition.

The shared visual instructions are our Style Bible. They keep the thick outlines, flat colors, card frame, typography, and composition stable across all generations. We also randomize collectible details. Common stickers appear more frequently, while gold, silver, black, and holographic borders are less common. Some generations receive a World Cup trophy or official ball as a secondary prop. Around one sticker in twenty gets a golden LEGENDAIRE badge.

The result is more than a photo filter. The same input can become a genuinely different collectible each time.

ProTip: separate stable visual rules from variable scenario instructions. It makes your prompt system easier to tune and prevents a change to one celebration from altering the visual identity of the whole collection.

When the AI remembered the wrong jerseys

The first stickers looked promising, but one detail immediately broke the illusion: the kits were wrong. For example, this result clearly uses an older France jersey. Nano Banana often generated older designs, including 2024-era jerseys. That is understandable - a text prompt can describe β€œthe official 2026 France home kit,” but the model still needs reliable visual information about a new design.

We solved this with multimodal reference images. For France, England, Spain, and Argentina, the backend now attaches a packshot of the official 2026 home jersey to the generation request. The prompt explicitly tells Nano Banana to reproduce its colors, pattern, collar, marks, and crest placement in the cartoon style. It also draws a strict boundary: This image is ONLY a clothing reference. Ignore any person, mannequin, face, body, pose, or background shown in it, and use it solely for the jersey design.

We applied the same technique to the official 2026 match ball. Whenever a scenario includes a football, the backend sends the ball image and asks the model to reproduce its base color, panel shapes, colored zones, and line patterns.

The complete request can therefore contain:

  • the user's portrait for identity;
  • a 2026 jersey packshot for clothing;
  • the official match-ball image for the ball design;
  • the assembled text prompt for the scene and visual rules.

The actual Gemini request follows that order:

const parts: Array<Record<string, unknown>> = [
  { inlineData: portrait },
  ...(jersey ? [{ inlineData: jersey }] : []),
  ...(ball ? [{ inlineData: ball }] : []),
  { text: prompt },
];
const response = await ai.models.generateContent({
  model: DEFAULT_MODEL,
  contents: [{ role: "user", parts }],
  config: {
    imageConfig: { aspectRatio: " 3:4 " },
  },
});

The ordering is intentional: the portrait remains the primary identity reference, followed by controlled visual assets and finally the instructions that explain how to use them. All of this happens on the backend. The browser sends the photo and business choices, but it never receives the Gemini API key or controls the raw production prompt.

There was one important gotcha. A jersey reference containing a recognizable face or head could make the image request fail with finishReason=IMAGE_OTHER and no generated image.

ProTip: prepare product references as clean packshots. Crop jersey images to the torso, remove faces and heads, keep the background simple, and use a reasonably sized compressed image. Reference quality directly affects both reliability and adherence.

Moving from Nano Banana 1 to Nano Banana 2

Our first production version used Nano Banana 1 through gemini-2.5-flash-image. It proved that the concept worked. It could transform a portrait, create the cartoon style, and follow imaginative football scenarios. But as our prompts gained more constraints, we needed stronger adherence: preserve the person's identity, copy a new jersey, use the correct ball, render the name, respect the card frame, and still create a dynamic scene.

We upgraded the production model to Nano Banana 2, exposed through gemini-3.1-flash-image. The improvement was not about adding more adjectives to the prompt. Nano Banana 2 followed the combined identity, reference-image, text, and layout instructions more reliably. That made it a better fit for a product in which small details - the correct collar, visible glasses, or an uncropped name - determine whether the sticker feels right.

We compared both versions with the same portraits, scenarios, and prompts before switching. Keeping the model name configurable also means we can repeat those A/B tests as the Gemini image family evolves.

The generation still uses a 1K output. For a fast, playful web experience, this gives us a practical balance between visual quality, latency, and cost. You can learn more about image generation in the official Gemini API documentation.

From a side project to real API limits

The first audience was exactly who we built it for: friends and family. Then people started generating several versions, trying another team, looking for a rarer border, and sharing the funniest results. That is great product feedback - and a fast way to discover API quotas.

At Gemini API Tier 1, our daily request limits became a real constraint. The API key is only the credential; the effective quota comes from the associated Gemini API project and usage tier. Once the studio became active, generation capacity mattered as much as prompt quality.

A big thank you to Guillaume Vernade, who helped us move to Tier 3 and give the experiment enough room for more people to play. This was a useful reminder: when an AI demo becomes shareable, usage can grow differently from a traditional application. One visit may trigger several expensive generation calls because exploration is part of the experience. Quotas, concurrency, retries, and graceful error messages belong in the product design from the beginning.

Thanks to a spending cap, we can also control how much we spend on new generations. Each sticker costs approximately $0.20 to generate, so the cap protects the experiment from an unexpectedly high bill.

Conclusion: now create your World Cup sticker

Sticker Studio started with one simple question: what if our friends and family were the players inside the pack? Building it taught us three practical lessons:

  1. Structured prompts turn isolated images into a coherent collection.
  2. Current visual references are essential when recent jerseys and equipment must be accurate.
  3. A stronger model and enough API capacity matter once people start experimenting.

But the main result is much simpler: it is fun. Friends and family have already generated 365 stickers. With the World Cup final finished, now is the perfect time to create yours, try another team, compare rare editions, and share the result.

πŸ‘‰ Create your own World Cup sticker with Sticker Studio
Which team, scenario, and rarity will you get?

IMPORTANT NOTE: Sticker Studio is a playful, unofficial fan project and is not affiliated with Panini or FIFA.

Comments

No comments yet. Start the discussion.