使用 Nano Banana API 打造 AI 图片生成与编辑工具

October, 25th 2025 8 min read

前言

最近 Google 发布了 Gemini 2.5 Flash Image 模型(代号 Nano Banana),这是一个强大的 AI 图片生成和编辑模型。今天我用 TypeScript + Bun 开发了一个简单易用的命令行工具,通过 AIHubMix 中转服务来调用这个 API,实现了图片生成和编辑功能。

技术栈

  • 运行时: Bun(快速的 JavaScript 运行时)
  • 语言: TypeScript
  • API: Google Gemini 2.5 Flash Image
  • 中转服务: AIHubMix

核心功能

1. 文本生成图片

通过自然语言描述生成图片,支持中英文提示词。

bash
12345
      # 中文提示词
bun run gen "一只可爱的猫咪在月光下弹吉他,动漫风格" -o cat.png

# 英文提示词
bun run gen "Beautiful sunset over ocean, realistic style" -o sunset.png
    

2. 智能图片编辑

这是我觉得最有意思的功能。不需要传统的图像蒙版(mask),只需要用自然语言描述想要的修改:

bash
1234567891011
      # 改变颜色
bun run edit house.png "把屋顶改成蓝色" -o house-blue.png

# 风格转换
bun run edit photo.jpg "转换成油画风格" -o painting.png

# 添加元素
bun run edit room.png "在墙上添加一幅现代艺术画" -o decorated.png

# 移除元素
bun run edit beach.jpg "移除照片中的其他人" -o solo.png
    

技术实现

1. API 调用封装

核心是一个 NanoBananaClient 类,封装了 AIHubMix 的 API 调用:

typescript
12345678910111213141516171819202122232425262728293031
      export class NanoBananaClient {
  private apiKey: string;
  private baseURL: string;
  private modelName: string;

  constructor(apiKey: string, options?: { baseURL?: string; model?: string }) {
    this.apiKey = apiKey;
    this.baseURL = options?.baseURL || "https://aihubmix.com/v1";
    this.modelName = options?.model || "gemini-2.5-flash-image";
  }

  async generateImage(prompt: string): Promise<string> {
    // 调用 AIHubMix API
    const response = await fetch(`${this.baseURL}/chat/completions`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${this.apiKey}`,
      },
      body: JSON.stringify({
        model: this.modelName,
        messages: [{ role: "user", content: [{ type: "text", text: prompt }] }],
        max_tokens: 8192,
        temperature: 1,
      }),
    });

    // 解析响应,提取 base64 图片数据
    // ...
  }
}
    

2. 响应格式处理

AIHubMix 返回的图片数据在 multi_mod_content 数组中,需要特殊处理:

typescript
1234567891011
      const data = await response.json();
const message = data.choices?.[0]?.message;

// AIHubMix 特有的响应格式
if (message.multi_mod_content && Array.isArray(message.multi_mod_content)) {
  for (const item of message.multi_mod_content) {
    if (item.inline_data?.data) {
      return item.inline_data.data; // base64 图片数据
    }
  }
}
    

3. 图片编辑实现

编辑图片时,需要将原图 base64 编码后连同提示词一起发送:

typescript
1234567891011121314151617181920212223242526
      async editImage(imagePath: string, prompt: string): Promise<string> {
  // 读取并编码图片
  const imageData = fs.readFileSync(imagePath);
  const base64Image = imageData.toString("base64");
  const mimeType = this.getMimeType(imagePath);

  // 构建请求
  const requestBody = {
    model: this.modelName,
    messages: [{
      role: "user",
      content: [
        {
          type: "image_url",
          image_url: { url: `data:${mimeType};base64,${base64Image}` }
        },
        { type: "text", text: prompt }
      ]
    }],
    max_tokens: 8192,
    temperature: 1,
  };

  // 发送请求并返回编辑后的图片
  // ...
}
    

4. 命令行工具

使用 Bun 的原生能力,创建了两个简单的 CLI 工具:

生成图片 (generate.ts)

typescript
1234567891011121314
      #!/usr/bin/env bun
import { NanoBananaClient } from "./nano-banana";

async function main() {
  const args = process.argv.slice(2);
  // 解析参数:提示词和输出文件名
  // ...

  const client = new NanoBananaClient(apiKey);
  const imageData = await client.generateImage(prompt);
  client.saveImage(imageData, outputFile);
}

main();
    

编辑图片 (edit.ts)

typescript
1234567891011121314
      #!/usr/bin/env bun
import { NanoBananaClient } from "./nano-banana";

async function main() {
  const args = process.argv.slice(2);
  // 解析参数:输入图片、编辑指令、输出文件名
  // ...

  const client = new NanoBananaClient(apiKey);
  const imageData = await client.editImage(inputImage, editPrompt);
  client.saveImage(imageData, outputFile);
}

main();
    

遇到的坑

1. 响应格式不一致

开始时发现有的请求成功,有的失败。通过打印完整响应发现,AIHubMix 返回的格式与标准 OpenAI 格式略有不同,图片数据在 multi_mod_content 而不是 content 字段中。

解决方案:添加了多层降级处理逻辑,先检查 multi_mod_content,再检查标准 content 字段。

2. 变量命名冲突

blendImages 方法中,content 变量被重复声明导致编译错误。

解决方案:将局部变量重命名为 contentParts 避免冲突。

3. 中文提示词支持

最初担心中文提示词可能不支持,但测试发现 Gemini 2.5 Flash Image 对中文的支持非常好。

实际效果

我测试了几个场景:

  1. 生成测试

    • 提示词:"一只可爱的猫咪"
    • 生成:1024x1024 的高质量图片
  2. 编辑测试

    • 原图:红色屋顶的房子
    • 指令:"Change the roof color to blue and add flowers in the garden"
    • 结果:屋顶变成蓝色,花园里添加了花朵

效果相当不错!模型能很好地理解编辑指令,并保持图片其他部分不变。

项目结构

plaintext
12345678910
      nano-banana/
├── generate.ts          # 生成图片命令行工具
├── edit.ts             # 编辑图片命令行工具
├── nano-banana.ts      # 核心库文件
├── package.json        # 项目配置
├── tsconfig.json       # TypeScript 配置
├── .env.example        # 环境变量模板
├── .gitignore         # Git 忽略配置
├── README.md          # 英文文档
└── 快速开始.md        # 中文快速指南
    

使用成本

通过 AIHubMix 调用,大约 ¥0.03-0.04 每张图片,相比直接调用 Google API 更加实惠和稳定。

快速开始

1. 安装依赖

bash
1
      bun install
    

2. 配置 API Key

bash
12
      cp .env.example .env
# 编辑 .env 文件,填入 AIHubMix API Key
    

3. 生成图片

bash
1
      bun run gen "你的图片描述" -o output.png
    

4. 编辑图片

bash
1
      bun run edit input.jpg "编辑指令" -o edited.png
    

后续计划

  1. 批量处理:支持批量生成或编辑多张图片
  2. 图片混合:实现多张图片混合功能(blendImages 方法已实现,待添加 CLI)
  3. 参数配置:支持自定义分辨率、风格强度等参数
  4. Web UI:考虑添加一个简单的 Web 界面

总结

这个项目展示了如何快速接入 AI 图片生成服务,通过简单的命令行工具就能实现强大的图片生成和编辑功能。Gemini 2.5 Flash Image 的语义编辑能力让图片处理变得异常简单,不需要专业的图像处理知识,只需要用自然语言描述想要的效果即可。

对于需要 AI 图片生成功能的开发者来说,这个工具可以作为很好的起点。代码简洁清晰,易于扩展和集成到自己的项目中。

参考资料


项目地址:(可以在这里添加你的 GitHub 仓库链接)

关键词:AI 图片生成、Gemini、Nano Banana、TypeScript、Bun、图片编辑


本文记录了使用 Gemini 2.5 Flash Image API 开发 AI 图片工具的完整过程,希望对你有帮助!