本案例将引导您一步步构建一个 Spring Boot 应用,演示如何利用 Spring AI Alibaba 的 Image 客户端功能,实现图像生成和处理。

1. 案例目标

我们将创建一个 Web 应用,演示如何使用 Spring AI Alibaba 集成 OpenAI 的图像生成功能:

  1. 图像生成 API:通过文本描述生成图像。
  2. 图像编辑功能:对生成的图像进行编辑和处理。

2. 技术栈与核心依赖

  • Spring Boot 3.x
  • Spring AI (用于对接 OpenAI 图像生成模型)
  • Maven (项目构建工具)

在 pom.xml 中,你需要引入以下核心依赖:

<dependencies>
    <!-- Spring Web 用于构建 RESTful API -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring AI OpenAI 模型启动器 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-model-openai</artifactId>
    </dependency>
</dependencies>

3. 项目配置

在 src/main/resources/application.yml 文件中,配置你的 OpenAI API Key。

server:
  port: 10009

spring:
  application:
    name: spring-ai-alibaba-openai-image-example
  ai:
    openai:
      api-key: ${AI_OPENAI_API_KEY}

重要提示:请将 AI_OPENAI_API_KEY 环境变量设置为你从 OpenAI 获取的有效 API Key。你也可以直接将其写在配置文件中,但这不推荐用于生产环境。

4. 项目结构

本示例项目采用标准的 Spring Boot 项目结构:

spring-ai-alibaba-image-example/openai-image/
├── .classpath
├── .project
├── .settings/
├── README.md
├── pom.xml
├── src/
│   └── main/
│       ├── java/
│       │   └── com/
│       │       └── alibaba/
│       │           └── cloud/
│       │               └── ai/
│       │                   └── example/
│       │                       └── image/
│       │                           └── openai/
│       │                               ├── OpenAIImageApplication.java
│       │                               └── controller/
│       │                                   └── OpenAIImageController.java
│       └── resources/
│           └── application.yml
└── target/

5. 编写 Java 代码

5.1 OpenAIImageApplication.java

Spring Boot 应用程序入口类。

package com.alibaba.cloud.ai.example.image.openai;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class OpenAIImageApplication {

    public static void main(String[] args) {

        SpringApplication.run(OpenAIImageApplication.class, args);
    }

}

5.2 OpenAIImageController.java

图像生成控制器类(目前为待实现状态)。

package com.alibaba.cloud.ai.example.image.openai.controller;


public class OpenAIImageController {

    // todo: not impl yet.

}

6. 实现图像生成功能

由于当前控制器类尚未实现,我们将提供一个完整的实现示例,展示如何使用 Spring AI 的 ImageClient 来生成图像。

6.1 完整的控制器实现

package com.alibaba.cloud.ai.example.image.openai.controller;

import org.springframework.ai.image.Image;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.ai.openai.OpenAiImageModel;
import org.springframework.ai.openai.api.OpenAiImageOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;


@RestController
@RequestMapping("/api/images")
public class OpenAIImageController {

    private final OpenAiImageModel imageModel;

    @Autowired
    public OpenAIImageController(OpenAiImageModel imageModel) {
        this.imageModel = imageModel;
    }

    /**
     * 生成图像
     * @param prompt 图像描述提示词
     * @param n 生成图像数量,默认为1
     * @param size 图像尺寸,默认为1024x1024
     * @return 生成的图像URL列表
     */
    @GetMapping("/generate")
    public List<String> generateImage(
            @RequestParam String prompt,
            @RequestParam(defaultValue = "1") int n,
            @RequestParam(defaultValue = "1024x1024") String size) {
        
        // 创建图像提示词
        ImagePrompt imagePrompt = new ImagePrompt(prompt,
                OpenAiImageOptions.builder()
                        .withN(n)  // 生成图像数量
                        .withSize(size)  // 图像尺寸
                        .build());
        
        // 调用模型生成图像
        ImageResponse imageResponse = imageModel.call(imagePrompt);
        
        // 提取图像URL
        return imageResponse.getResults().stream()
                .map(Image::getUrl)
                .toList();
    }

    /**
     * 生成图像变体
     * @param imageUrl 原始图像URL
     * @param n 生成变体数量,默认为1
     * @param size 图像尺寸,默认为1024x1024
     * @return 生成的图像变体URL列表
     */
    @GetMapping("/variations")
    public List<String> generateImageVariations(
            @RequestParam String imageUrl,
            @RequestParam(defaultValue = "1") int n,
            @RequestParam(defaultValue = "1024x1024") String size) {
        
        // 创建图像变体提示词
        ImagePrompt imagePrompt = new ImagePrompt("Create variations of this image",
                OpenAiImageOptions.builder()
                        .withN(n)
                        .withSize(size)
                        .withImage(imageUrl)  // 原始图像URL
                        .build());
        
        // 调用模型生成图像变体
        ImageResponse imageResponse = imageModel.call(imagePrompt);
        
        // 提取图像URL
        return imageResponse.getResults().stream()
                .map(Image::getUrl)
                .toList();
    }

    /**
     * 编辑图像
     * @param imageUrl 原始图像URL
     * @param maskImageUrl 掩码图像URL(指定要编辑的区域)
     * @param prompt 编辑描述
     * @param n 生成图像数量,默认为1
     * @param size 图像尺寸,默认为1024x1024
     * @return 编辑后的图像URL列表
     */
    @GetMapping("/edit")
    public List<String> editImage(
            @RequestParam String imageUrl,
            @RequestParam String maskImageUrl,
            @RequestParam String prompt,
            @RequestParam(defaultValue = "1") int n,
            @RequestParam(defaultValue = "1024x1024") String size) {
        
        // 创建图像编辑提示词
        ImagePrompt imagePrompt = new ImagePrompt(prompt,
                OpenAiImageOptions.builder()
                        .withN(n)
                        .withSize(size)
                        .withImage(imageUrl)  // 原始图像URL
                        .withMask(maskImageUrl)  // 掩码图像URL
                        .build());
        
        // 调用模型编辑图像
        ImageResponse imageResponse = imageModel.call(imagePrompt);
        
        // 提取图像URL
        return imageResponse.getResults().stream()
                .map(Image::getUrl)
                .toList();
    }
}

7. 运行与测试

  1. 启动应用:运行 Spring Boot 主程序 OpenAIImageApplication
  2. 使用浏览器或 API 工具(如 Postman, curl)进行测试

测试 1:生成图像

使用以下 URL 生成一张"一只可爱的小猫在花园里玩耍"的图像。

http://localhost:10009/api/images/generate?prompt=一只可爱的小猫在花园里玩耍

预期响应

[
    "https://oaidalleapiprodscus.blob.core.windows.net/private/..."
]

测试 2:生成多张图像

使用以下 URL 生成两张"夕阳下的城市天际线"的图像。

http://localhost:10009/api/images/generate?prompt=夕阳下的城市天际线&n=2

预期响应

[
    "https://oaidalleapiprodscus.blob.core.windows.net/private/...",
    "https://oaidalleapiprodscus.blob.core.windows.net/private/..."
]

测试 3:生成图像变体

使用以下 URL 为指定图像生成变体。

http://localhost:10009/api/images/variations?imageUrl=https://example.com/image.jpg&n=2

预期响应

[
    "https://oaidalleapiprodscus.blob.core.windows.net/private/...",
    "https://oaidalleapiprodscus.blob.core.windows.net/private/..."
]

测试 4:编辑图像

使用以下 URL 编辑指定图像。

http://localhost:10009/api/images/edit?imageUrl=https://example.com/image.jpg&maskImageUrl=https://example.com/mask.jpg&prompt=将图像中的天空改为星空

预期响应

[
    "https://oaidalleapiprodscus.blob.core.windows.net/private/..."
]

8. 实现思路与扩展建议

实现思路

本案例的核心思想是利用 Spring AI 的抽象层简化 AI 图像生成功能的集成。通过 Spring AI 提供的 ImageClient 和相关类,我们可以:

  • 简化 API 调用:无需直接处理 HTTP 请求和响应,Spring AI 提供了高级抽象。
  • 统一接口:无论是 OpenAI 还是其他 AI 图像生成服务,都可以通过相同的接口进行调用。
  • 类型安全:使用强类型对象表示请求和响应,减少错误。

扩展建议

  • 图像存储:将生成的图像保存到本地文件系统或云存储(如阿里云 OSS、AWS S3),并提供持久化的访问链接。
  • 异步处理:对于复杂的图像生成任务,可以实现异步处理机制,避免长时间阻塞 HTTP 请求。
  • 图像缓存:对相同提示词生成的图像进行缓存,提高响应速度并减少 API 调用成本。
  • 用户界面:开发一个前端界面,允许用户输入提示词、选择参数并预览生成的图像。
  • 图像处理集成:集成其他图像处理库(如 OpenCV、ImageJ),对生成的图像进行进一步处理。
  • 多模型支持:扩展应用以支持多个图像生成模型(如 DALL-E 2、DALL-E 3、Stable Diffusion 等)。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐