Back to all skills

nano-banana

Generate images from text prompts or edit existing images using Google Nano Banana (Gemini image generation) via Rebyte data API. Use for text-to-image generation or image-to-image editing/enhancement. Triggers include "generate image", "create image", "make a picture", "draw", "illustrate", "image of", "picture of", "edit image", "modify image", "enhance image", "style transfer", "nano banana".

Featured Design

Run this skill in the cloud

No local installation needed
All dependencies pre-installed
Secure isolated VM environment

Skill Documentation

# Nano Banana - Image Generation API

Generate images from text prompts or edit existing images using Google Nano Banana (Gemini's native image generation).

## Authentication

**IMPORTANT:** All API requests require authentication. Get your auth token and API URL by running:

```bash
AUTH_TOKEN=$(/home/user/.local/bin/rebyte-auth)
API_URL=$(python3 -c "import json; print(json.load(open('/home/user/.rebyte.ai/auth.json'))['sandbox']['relay_url'])")
```

Include the token in all API requests as a Bearer token, and use `$API_URL` as the base for all API endpoints.

## Models

| Model | ID | Best For | Max Resolution |
|-------|-----|----------|----------------|
| **Flash** | `flash` | Fast generation, high-volume tasks | 1024px |
| **Pro** | `pro` | Professional quality, complex prompts | 4K |

---

## Text-to-Image Generation

Create an image from a text description.

```bash
curl -X POST "$API_URL/api/data/images/generate" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A futuristic cityscape at sunset with flying cars",
    "model": "flash",
    "aspectRatio": "16:9"
  }'
```

---

## Image-to-Image Generation

Edit, enhance, or transform an existing image by providing it as base64.

```bash
curl -X POST "$API_URL/api/data/images/generate" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Transform this into a watercolor painting style",
    "image": "<base64-encoded-image>",
    "imageMimeType": "image/png",
    "model": "pro"
  }'
```

**Use Cases:**
- **Style Transfer**: "Make this photo look like a Van Gogh painting"
- **Enhancement**: "Improve the lighting and colors"
- **Editing**: "Remove the background and replace with a beach scene"
- **Text Correction**: "Fix the text in this image: change 'Helo' to 'Hello'"

---

## Parameters

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `prompt` | string | Yes | - | Text description or editing instructions |
| `image` | string | No | - | Base64-encoded source image (for image-to-image) |
| `imageMimeType` | string | No | `image/png` | MIME type: `image/png`, `image/jpeg`, `image/webp` |
| `model` | string | No | `flash` | `flash` (fast, 1024px) or `pro` (high-quality, up to 4K) |
| `aspectRatio` | string | No | `1:1` | Output aspect ratio |
| `imageSize` | string | No | `1K` | `1K`, `2K`, or `4K` (4K only with `pro` model) |

**Aspect Ratios:**

| Ratio | Use Case |
|-------|----------|
| `1:1` | Square (social media, icons) |
| `16:9` | Landscape (presentations, banners) |
| `9:16` | Portrait (mobile, stories) |
| `4:3` | Standard landscape |
| `3:4` | Standard portrait |
| `21:9` | Ultra-wide (cinematic) |
| `2:3`, `3:2`, `4:5`, `5:4` | Various formats |

---

## Response

```json
{
  "image": {
    "base64": "iVBORw0KGgoAAAANSUhEUgAA...",
    "mimeType": "image/png",
    "dataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
  },
  "description": "A vibrant futuristic cityscape..."
}
```

| Field | Description |
|-------|-------------|
| `image.base64` | Base64-encoded image data |
| `image.mimeType` | Image MIME type (typically `image/png`) |
| `image.dataUrl` | Ready-to-use data URL for HTML/CSS |
| `description` | Model's description of the generated image |

---

## Using with Python

```python
import subprocess
import requests
import base64
import json
from pathlib import Path

# Get auth token and API URL
AUTH_TOKEN = subprocess.check_output(["/home/user/.local/bin/rebyte-auth"]).decode().strip()
with open('/home/user/.rebyte.ai/auth.json') as f:
    API_URL = json.load(f)['sandbox']['relay_url']

HEADERS = {"Authorization": f"Bearer {AUTH_TOKEN}"}

def generate_image(
    prompt: str,
    image_path: str = None,
    model: str = "flash",
    aspect_ratio: str = "1:1",
    image_size: str = "1K"
) -> dict:
    """Generate an image from text, or edit an existing image."""
    payload = {
        "prompt": prompt,
        "model": model,
        "aspectRatio": aspect_ratio,
        "imageSize": image_size
    }

    # Add source image for image-to-image
    if image_path:
        image_data = Path(image_path).read_bytes()
        payload["image"] = base64.b64encode(image_data).decode()
        # Detect mime type from extension
        ext = Path(image_path).suffix.lower()
        mime_map = {'.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.webp': 'image/webp'}
        payload["imageMimeType"] = mime_map.get(ext, 'image/png')

    response = requests.post(
        f"{API_URL}/api/data/images/generate",
        headers=HEADERS,
        json=payload
    )
    return response.json()

def save_image(result: dict, filepath: str) -> None:
    """Save generated image to a file."""
    if "image" in result:
        image_data = base64.b64decode(result["image"]["base64"])
        Path(filepath).write_bytes(image_data)
        print(f"Saved to {filepath}")
    else:
        print(f"Error: {result.get('error', 'Unknown error')}")

# Example 1: Text-to-image
result = generate_image(
    prompt="A serene mountain landscape at dawn with mist in the valley",
    aspect_ratio="16:9"
)
save_image(result, "landscape.png")

# Example 2: Image-to-image (style transfer)
result = generate_image(
    prompt="Transform this into a watercolor painting",
    image_path="photo.jpg",
    model="pro"
)
save_image(result, "watercolor.png")

# Example 3: Image editing
result = generate_image(
    prompt="Remove the background and add a sunset beach scene",
    image_path="portrait.png",
    model="pro"
)
save_image(result, "portrait_beach.png")
```

---

## Using with Node.js

```javascript
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');

// Get auth token and API URL
const AUTH_TOKEN = execSync('/home/user/.local/bin/rebyte-auth').toString().trim();
const authConfig = JSON.parse(fs.readFileSync('/home/user/.rebyte.ai/auth.json'));
const API_URL = authConfig.sandbox.relay_url;

async function generateImage(prompt, options = {}) {
  const payload = {
    prompt,
    model: options.model || 'flash',
    aspectRatio: options.aspectRatio || '1:1',
    imageSize: options.imageSize || '1K'
  };

  // Add source image for image-to-image
  if (options.imagePath) {
    const imageBuffer = fs.readFileSync(options.imagePath);
    payload.image = imageBuffer.toString('base64');
    const ext = path.extname(options.imagePath).toLowerCase();
    const mimeMap = {'.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.webp': 'image/webp'};
    payload.imageMimeType = mimeMap[ext] || 'image/png';
  }

  const response = await fetch(`${API_URL}/api/data/images/generate`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${AUTH_TOKEN}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
  });
  return response.json();
}

function saveImage(result, filepath) {
  if (result.image) {
    const buffer = Buffer.from(result.image.base64, 'base64');
    fs.writeFileSync(filepath, buffer);
    console.log(`Saved to ${filepath}`);
  } else {
    console.error('Error:', result.error || 'Unknown error');
  }
}

// Example: Text-to-image
(async () => {
  const result = await generateImage(
    'A neon-lit cyberpunk street scene at night',
    { aspectRatio: '21:9' }
  );
  saveImage(result, 'cyberpunk.png');
})();

// Example: Image-to-image
(async () => {
  const result = await generateImage(
    'Make this look like a Studio Ghibli animation',
    { imagePath: 'photo.jpg', model: 'pro' }
  );
  saveImage(result, 'ghibli_style.png');
})();
```

---

## Prompt Tips

### Text-to-Image
```
Bad:  "A dog"
Good: "A golden retriever puppy playing in autumn leaves, warm sunlight"
```

### Image-to-Image
```
Style Transfer: "Transform into oil painting style", "Make it look like anime"
Enhancement: "Improve lighting and contrast", "Make colors more vibrant"
Editing: "Remove the person in the background", "Add a rainbow to the sky"
Text Fix: "Change the text from 'Helo' to 'Hello'"
```

---

## Model Comparison

| Feature | Flash | Pro |
|---------|-------|-----|
| Speed | Fast | Slower |
| Max Resolution | 1024px | 4K |
| Complex Prompts | Good | Excellent |
| Text Rendering | Good | Sharp |
| Image-to-Image | Good | Excellent |
| Best For | Quick iterations, previews | Final assets, print, complex edits |

---

## Error Handling

**Missing or Invalid Auth Token:**
```json
{
  "error": "Missing sandbox token"
}
```
Solution: Run `rebyte-auth` and include the token in your request.

**No Image Generated:**
```json
{
  "error": "No image generated",
  "message": "SAFETY"
}
```
This occurs when the prompt triggers content safety filters.

---

## Important Notes

- All generated images include invisible **SynthID watermarking**
- Images are generated server-side; base64 responses can be large
- The `pro` model takes longer but produces higher quality
- 4K resolution is only available with the `pro` model
- Content safety filters may block certain prompts
- For image-to-image, the source image is sent as base64 in the request body

Published by rebyteai

This skill works with Claude Code, Cursor, Windsurf, Gemini CLI, and other AI coding agents.

rebyte.ai - The only skill marketplace where you can run skills directly in the cloud

No downloads. No configuration. Just sign in and start using AI skills immediately.