Skip to content
AI Growth Lab
Navigation menu
AI Growth Lab

Loading lesson…

CoursesContactPrivacy

Curriculum based on Datawhale / Easy Vibe · CC BY-NC-SA 4.0

← Back to course

Full-Stack Developer

Image Assets & Drawing Agents
  1. Asset Production & Agent Building
  2. Chapter 2: A More Obedient Image Generation Assistant — Using Lovart as an Example
  3. Chapter 3: Build Your Own Smart Drawing Assistant
UI Design Foundations
  1. AI Design Basics
  2. Chapter 3: A Panorama of Frontend Design Tools in the AI Era
  3. Chapter 4: Hands-On 1 — Imitating "Someone Else's Web Page" to Match
  4. Chapter 6: Make a Big-Tech Design System Your Own
Design Tools & Interface Styling
  1. Figma & MasterGo Basics
  2. 2. Figma basics
  3. 3. MasterGo basics
  4. UI Design Specs & Multi-Product Interface
  5. LLM & Skills Interface Beautification
From Design to Frontend Code
  1. Design Prototype to Project Code
  2. Modern Component Libraries
  3. 3. Scenario One: Build a Product Landing Page with HeroUI
Databases & Supabase
  1. Database & Supabase
  2. 2. Supabase
  3. 2.1 Creating Your First SQL Data Table
  4. 3. Your First SQL Application
  5. 4. Building Your First Supabase Application
Backend APIs & Integration
  1. Backend API Design & Development
Git & GitHub Workflow
  1. Git & GitHub Workflow
  2. What is GitHub?
  3. Bind local SSH to GitHub
  4. Use Trae for GitHub operations
Website Deployment & Zeabur
  1. Put Your Website Online (Easy): One-Click PaaS (Vercel/Zeabur)
  2. Deploy Dify with Zeabur
  3. Deploy a Snake game with Zeabur and Trae
Cloud Servers & Advanced Deployment
  1. Put Your Website Online (Advanced): Set Up Your Own VPS
  2. 4. Three Typical Deployment Scenarios
  3. 6. Cloud Provider Services Deep Dive (Beyond VPS)
  4. 8. 🎯 Vibecoding Deployment Workflow: Let AI Be Your DevOps
CLI AI Coding Tools
  1. Modern CLI Dev Tools
  2. Codex
  3. More Use Cases for CLI AI Coding Tools
Payments & Billing Integration
  1. Stripe Payment Integration
  2. Payment Confirmation & Subscription Events
  3. Choosing Other Payment Solutions
Comprehensive Projects
  1. Hogwarts Portraits Project
  2. AI Marketing Copywriting SaaS
  3. Online Exam & Management System
  4. Modern AI Image SaaS
  5. Custom Dify Agent Platform
On this page
  • Chapter 1: Generate Your First Image Asset in 1 Minute

Lesson Contents

  1. Chapter 1: Generate Your First Image Asset in 1 Minute
4. Practical scenario one: redesign a landing page with aesthetic prompts
5. Becoming a Supabase Master
Travel Planning Agent Platform
  • Spring Boot Movie Recommender
  • Grocery Microservices System
  • Go Traffic Data Platform
  • Starting from NanoBanana: Build Your Own Asset Production Agent

    Chapter 1: Generate Your First Image Asset in 1 Minute

    Before we dive into design, style, or prompting, let's generate the first image with the fewest steps possible.

    1.1 Meet NanoBanana

    Before we discuss design styles and prompt engineering, let's address something even more important: confirming that you can actually generate an image.

    Today's mainstream large models already possess image generation and editing capabilities. These models are commonly known as generative models.

    To keep the process as simple as possible, this tutorial uses a model that already has stable image generation and editing capabilities — NanoBanana. It is an image generation model released by Google, officially named Gemini 3.1 Flash Image Preview, which supports generating images directly through natural language and also supports editing existing images.

    Nano Banana model logo.

    In terms of capabilities, it is not fundamentally different from other models you may have heard of (such as GPT-4o, Claude, Qwen, Midjourney, etc.): you provide a description, and the model generates the result.

    Qwen3 model logo.GPT-4o model logo.Claude 3 model logo.

    You can think of it as a "paintbrush." In this chapter, we only care about one thing: 👉 Whether this paintbrush can make its first stroke in your hands.

    In practice, NanoBanana can be used directly through official platforms like Google AI Studio, or integrated into development workflows via API. This tutorial uses the API approach. The NanoBanana 2 model has also been released, and you can try using the latest large model.

    1.2 "Hello World" Level Generation

    Before you start, you only need to complete these three steps:

    1. Create a new folder in Trae

    TRAE model settings.

    1. Create a new Python file

    TRAE application menu.

    TRAE model selector.

    TRAE model configuration dialog.

    1. Paste the complete code below

    Trae will automatically handle the required environment setup and dependency installation — no additional configuration needed.

    The code uses NanoBanana's API Key. We won't go into the application process here — as long as you can obtain and fill in the corresponding parameters, you're good. At this stage, we don't aim to understand every line of code, just that it runs successfully.

    # /// script
    # dependencies = [
    #  "gradio>=4.0.0",
    #  "pillow>=10.0.0",
    #  "requests>=2.31.0",
    # ]
    # ///
    
    import gradio as gr
    import requests
    import base64
    from PIL import Image
    import io
    import os
    import time
    import re
    from typing import Optional, Dict, Any, List
    
    # Configure API information
    NANOBANANA_API_URL: str = "YOUR API URL"
    NANOBANANA_API_KEY: str = "YOUR API KEY"
    OUTPUT_DIR: str = "outputs"
    
    # Ensure output directory exists
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    
    def image_to_base64_data_uri(image: Image.Image) -> str:
        """
        Convert a PIL image to an OpenAI API compatible data URI format.
        """
        buffer = io.BytesIO()
        # Convert to PNG for compatibility
        image.save(buffer, format="PNG")
        encoded = base64.b64encode(buffer.getvalue()).decode('utf-8')
        return f"data:image/png;base64,{encoded}"
    
    def base64_to_image(base64_str: str) -> Optional[Image.Image]:
        """
        Convert a pure base64 string to a PIL Image.
        """
        try:
            image_bytes = base64.b64decode(base64_str)
            return Image.open(io.BytesIO(image_bytes))
        except Exception as e:
            print(f"Base64 decoding failed: {e}")
            return None
    
    def extract_base64_from_response(content: Any) -> Optional[str]:
        """
        Core parsing logic: Extract image Base64 data from API response content.
        Compatible with both Markdown format and structured list format.
        """
        if not content:
            return None
    
        base64_data = None
    
        # 1. Try structured extraction (List)
        # Corresponding response format: [{"type": "image_url", "image_url": {"url": "data:..."}}]
        if isinstance(content, list):
            for part in reversed(content):  # Search in reverse, latest images are usually at the end
                if isinstance(part, dict):
                    # Check image_url or output_image field
                    img_field = part.get("image_url") or part.get("image") or part.get("output_image")
                    if isinstance(img_field, dict):
                        url = img_field.get("url", "")
                        if url.startswith("data:image/") and "," in url:
                            return url.split(",", 1)[1].strip()
    
            # If no structured images in list, try concatenating text from list items to find Markdown
            text_parts = [
                str(p.get("text", ""))
                for p in content
                if isinstance(p, dict) and p.get("type") in ["text", "input_text"]
            ]
            content_str = "".join(text_parts)
        else:
            content_str = str(content)
    
        # 2. Try Markdown regex extraction (String)
        # Corresponding response format: "Here is your image: ![img](data:image/png;base64,AAAA...)"
        pattern = re.compile(r"!\[.*?\]\((data:image/[^;]+;base64,[^)]+)\)", re.IGNORECASE)
        match = pattern.search(content_str)
    
        if match:
            data_url = match.group(1)
            if "," in data_url:
                return data_url.split(",", 1)[1].strip()
    
        return None
    
    def synthesize(prompt: str, input_image: Optional[Image.Image]) -> Optional[Image.Image]:
        """
        Call the Nanobanana API for generation.
        """
        if not prompt or not prompt.strip():
            gr.Warning("Please enter a prompt")
            return None
    
        print(f">>> Starting task: {prompt[:50]}...")
    
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {NANOBANANA_API_KEY}"
        }
    
        # Build payload conforming to OpenAI Vision / Chat standard
        messages = []
    
        if input_image is not None:
            # Image-to-image / multimodal input mode
            print(">>> Input image detected, using multimodal mode")
            img_base64 = image_to_base64_data_uri(input_image)
            messages.append({
                "role": "user",
                "content": [
                    {"type": "text", "text": prompt},
                    {"type": "image_url", "image_url": {"url": img_base64}}
                ]
            })
        else:
            # Text-to-image mode
            messages.append({
                "role": "user",
                "content": prompt
            })
    
        payload = {
            "messages": messages,
            # Use the model verified in the first code section
            "model": "gemini-2.5-flash-image",
            # Optional parameters, depending on API support
            "stream": False
        }
    
        try:
            # Increase timeout, image generation is usually slower
            response = requests.post(NANOBANANA_API_URL, headers=headers, json=payload, timeout=120)
    
            # Check HTTP status
            if response.status_code != 200:
                error_msg = f"API request failed: {response.status_code} - {response.text}"
                print(error_msg)
                gr.Error(error_msg)
                return None
    
            result = response.json()
            # Debug: Print first part of response for debugging
            print(f"API raw response (truncated): {str(result)[:200]}...")
    
            # Extract Content
            content = None
            if "choices" in result and len(result["choices"]) > 0:
                content = result["choices"][0].get("message", {}).get("content")
    
            if not content:
                gr.Warning("No content field in API response")
                return None
    
            # Use the previously verified logic to extract Base64
            base64_str = extract_base64_from_response(content)
    
            if base64_str:
                output_image = base64_to_image(base64_str)
                if output_image:
                    return output_image
    
            # If no image was extracted, the model may have refused or only returned text
            text_content = str(content) if not isinstance(content, list) else " ".join([str(x) for x in content])
            gr.Info(f"No image generated, model returned text: {text_content[:100]}...")
            return None
    
        except requests.exceptions.Timeout:
            gr.Error("Request timed out, please try again later")
            return None
        except Exception as e:
            import traceback
            traceback.print_exc()
            gr.Error(f"An unknown error occurred: {str(e)}")
            return None
    
    # Gradio interface configuration
    with gr.Blocks(title="Nanobanana Image Generator") as app:
        gr.Markdown("# 🍌 Nanobanana Text/Image to Image")
        gr.Markdown("Based on Gemini-2.5-Flash-Image model, supports text-to-image and image-to-image.")
    
        with gr.Row():
            with gr.Column():
                prompt_input = gr.Textbox(
                    label="Prompt",
                    placeholder="e.g.: A cyberpunk cat holding a neon sign...",
                    lines=3
                )
                image_input = gr.Image(
                    label="Reference Image (optional, for image-to-image)",
                    type="pil",
                    height=300
                )
                submit_btn = gr.Button("Start Generation", variant="primary")
    
            with gr.Column():
                image_output = gr.Image(label="Generation Result", format="png")
    
        submit_btn.click(
            fn=synthesize,
            inputs=[prompt_input, image_input],
            outputs=image_output
        )
    
    if __name__ == "__main__":
        app.launch(share=True)
    

    When Trae indicates a successful run, click the local link it provides (usually http://127.0.0.1:7860).

    Image generator in the editor preview.

    If everything is working correctly, you'll see a functional AI drawing interface.

    This interface may look simple, but it already has the two most core capabilities of commercial-grade drawing tools: text-to-image and image-to-image.

    • Left side: Command Area (Input Zone) — this is where you give instructions.
    • Prompt (text box): Enter your creative description (English is recommended).
    • Input Image (reference image box):
      • Text-to-image mode: Keep this empty.
      • Image-to-image mode: Drag a local image here, and the AI will use it as a base for creation.
    • Submit button: Click to send your instruction and start generation.
    • Right side: Display Area (Output Zone) — where the magic happens, generated results will appear here.

    Empty Nano Banana image generator.

    Now we can try generating your first image!

    The prompt used in this example is:

    A red apple

    This is a deliberately simplified example that doesn't include any style or parameter descriptions.

    Actual Process

    After running the code, the process can be summarized in three steps:

    1. Send the text description to the model
    2. The model generates the corresponding image
    3. The image is saved as a local file

    After a few seconds, you'll see the generated result locally. Since model generation is random, the same prompt will produce different results. You can generate multiple times and choose your favorite image.

    Generated apple photograph.Apple image variation.

    You can also enrich your prompt by giving it more description and constraints. For example, the following prompt will produce a more distinctive image.

    "A hyper-realistic close-up of a fresh red apple with water droplets on its skin, sitting on a dark rustic wooden table. Cinematic dramatic lighting, rim light, shallow depth of field, bokeh background, 8k resolution, macro photography."
    

    Apple close-up result.

    Click download in the Output Image area to save the image locally.

    Image download control.

    1.3 Common Asset Generation Scenarios for Image Models

    In real-world work, large model image generation is more often used for efficiently producing design assets rather than creating individual art pieces.

    When you look at the popular cases from design-focused marketing accounts, you'll find that most of their output falls into two categories:

    • Text-to-image (from 0 to 1)
    • Reference-based image generation (from 1 to N)

    One: Text-to-Image — Quickly Obtaining Design Assets

    This category focuses on efficiency. When you need to fill in design gaps (such as empty states, avatars, illustrations), AI essentially serves as an instantly generated image library.

    1. Generating UI Design Assets

    • Popular trend: Glassmorphism and clay-style 3D icons commonly seen on Dribbble
    • Common presentation: Transparent materials, edge glow, candy-colored function or weather icons

    Example Prompt:

    A set of 3D weather icons (sun, cloud, rain), glassmorphism style, frosted glass texture, soft pastel gradient colors, soft studio lighting, isometric view, transparent background, 4k.

    Generated translucent icons.

    1. Generating Logos

    • Popular trend: Minimalist lines, geometric combinations for tech-style logos
    • Common presentation: Black and white color scheme, negative space design, clear brand identity

    Example Prompt:

    Minimalist vector logo design for a tech brand "Coffee Code", combining a coffee cup with coding brackets < >, flat design, solid black lines, white background, Paul Rand style, svg.

    Coffee Code logo result.

    1. Generating Website User Avatars

    • Popular trend: 3D virtual avatars commonly used on SaaS websites to avoid real-person copyright issues
    • Common presentation: Friendly expressions, cartoon proportions, leaning towards Pixar or Memoji style

    Example Prompt:

    Close-up portrait of a friendly young tech professional, smiling, Memoji 3D style, clay render, bright colors, soft lighting, solid plain background, Pixar character design.

    Generated character portrait.

    1. Generating Article Illustrations

    • Popular trend: Abstract flat illustrations commonly seen on tech company blogs
    • Common presentation: Purple-blue color scheme, exaggerated character proportions, floating UI elements

    Example Prompt:

    Editorial flat illustration representing remote work, a person sitting on a giant globe using a laptop, corporate memphis art style, vibrant colors (purple and teal), vector texture.

    Colorful illustration result.

    Two: Reference-Based Image Generation — Maintaining Visual Consistency

    This category focuses more on scalability. It's used when you already have a satisfactory main visual and need to generate an entire set of consistently styled assets.

    1. A Set of Buttons or Interactive Assets Similar to the Main Visual

    In game development, UI consistency is crucial. Suppose you already have a "PLAY" button for your main interface and now need to expand it into a complete set of uniformly styled function buttons (such as pause, settings, home). Relying solely on hand-drawing makes it difficult to ensure that each button is perfectly consistent in gloss, perspective, and color values.

    Basic Operation Flow:

    1. Save the existing blue "PLAY" button image

    Blue Play button asset.

    1. Drag it into the Input Image area as a reference template for subsequent generation
    2. Keep the style description in the prompt unchanged, only modify the main subject content

    With this flow, as long as you replace the subject description, you can get buttons with different functions but consistent styles.

    Example Prompt:

    Variant A: Pause Button (Icon Type)

    A capsule-shaped game UI button with a white pause icon (two vertical bars) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality.

    Pause button variation.

    Variant B: Settings Button (Complex Icon)

    A capsule-shaped game UI button with a white gear icon (settings symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality.

    Settings button variation.

    Variant C: Replay Button (Shape Change)

    If you need to change the button shape, you can directly describe the shape in the prompt. The model will attempt to change the structure while preserving the material characteristics.

    A round game UI button with a white circular arrow icon (replay symbol) inside. Same glossy blue jelly style, shiny plastic texture, white thick outline, vector illustration, high quality.

    Refresh button variation.

    Through this set of operations, you can not only replace button functions and icons but even change button shapes, while all generated results remain highly consistent in material, color scheme, and lighting. This is exactly the core value of large models in design asset generation scenarios.

    Previous
    Sign in to track progress
    Next