跳到主要内容
版本:1.1.5

Image Generation

Spring AI 通过 ImageModel 接口统一了 OpenAI DALL-E、Azure OpenAI、Stability AI 和 ZhiPuAI 四家厂商的图片生成能力,支持参数化控制尺寸、风格、生成数量。


1. 架构定位

ImageModel 是图片生成的统一入口,支持 OpenAI、Azure OpenAI、Stability AI 等厂商。通过自动注入即可使用,也可手动创建。


2. 图片生成模型

ImageModel 是单一方法的函数式接口。

2.1 自动注入

引入任一厂商 Starter 后,ImageModel 由 Spring Boot 自动配置提供。

配置项说明
spring.ai.openai.api-keyOpenAI API 密钥
spring.ai.openai.image.options.model模型名称,如 dall-e-3
@RestController
public class ImageController {

private final ImageModel imageModel;

public ImageController(ImageModel imageModel) {
this.imageModel = imageModel;
}

@GetMapping("/image")
public String generate(@RequestParam String prompt) {
ImageResponse response = imageModel.call(new ImagePrompt(prompt));
return response.getResult().getOutput().getUrl();
}
}

2.2 手动创建

当不使用 Spring Boot 自动配置时,可直接实例化具体实现。

完整示例:ManualImageDemo.java
ManualImageDemo.java
public class ManualImageDemo {

public static void main(String[] args) {
OpenAiImageApi imageApi = OpenAiImageApi.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();

OpenAiImageOptions options = OpenAiImageOptions.builder()
.model("dall-e-3")
.quality("hd")
.N(1)
.build();

OpenAiImageModel imageModel = OpenAiImageModel.builder()
.openAiImageApi(imageApi)
.defaultOptions(options)
.build();

ImageResponse response = imageModel.call(
new ImagePrompt("一只在月光下弹吉他的猫,赛博朋克风格"));
System.out.println("图片 URL: " + response.getResult().getOutput().getUrl());
}
}

3. 数据结构

3.1 提示词封装

ImagePrompt 封装提示词消息和选项,有 5 种构造方式。

// 最简:纯文本
ImagePrompt p1 = new ImagePrompt("一只坐在窗边的橘猫,梵高风格");

// 文本 + 选项
ImagePrompt p2 = new ImagePrompt("未来城市", ImageOptionsBuilder.builder()
.width(1024).height(1024).style("vivid").build());

// 单条加权消息 + 选项
ImagePrompt p3 = new ImagePrompt(
new ImageMessage("画面主体:橘猫", 1.5f),
ImageOptionsBuilder.builder().build());

// 多条加权消息
ImageMessage msg1 = new ImageMessage("画面主体:橘猫", 1.0f);
ImageMessage msg2 = new ImageMessage("背景:星空", 0.5f);
ImagePrompt p4 = new ImagePrompt(List.of(msg1, msg2));

// 多条消息 + 选项
ImagePrompt p5 = new ImagePrompt(
List.of(msg1, msg2),
ImageOptionsBuilder.builder().model("dall-e-3").build());

3.2 提示词消息

ImageMessage 封装一段提示词文本及其权重(权重对 Stability AI 的多提示词架构尤为重要)。

ImageMessage message = new ImageMessage("一只白猫", 1.0f);

String text = message.getText(); // "一只白猫"
Float weight = message.getWeight(); // 1.0

3.3 响应结果

ImageResponse response = imageModel.call(new ImagePrompt("未来城市"));

// 遍历所有生成结果
List<ImageGeneration> results = response.getResults();
for (ImageGeneration gen : results) {
Image image = gen.getOutput();
System.out.println("URL: " + image.getUrl());
System.out.println("Base64: " + image.getB64Json());
}

// 获取第一个结果
ImageGeneration first = response.getResult();

// 响应元数据
ImageResponseMetadata metadata = response.getMetadata();
System.out.println("创建时间: " + metadata.getCreated());

3.4 图片数据

一张生成的图片,包含 URL 或 Base64 编码数据。

Image image = new Image("https://example.com/image.png", null);

String url = image.getUrl(); // 图片访问 URL
String b64 = image.getB64Json(); // Base64 编码数据(Stability AI 以此为主)

4. 使用方式

4.1 基础图片生成

完整示例:SimpleImageDemo.java
SimpleImageDemo.java
@Component
public class SimpleImageDemo implements CommandLineRunner {

private final ImageModel imageModel;

public SimpleImageDemo(ImageModel imageModel) {
this.imageModel = imageModel;
}

@Override
public void run(String... args) {
ImageResponse response = imageModel.call(
new ImagePrompt("一座漂浮在云端的蒸汽朋克城市")
);

Image image = response.getResult().getOutput();
System.out.println("生成图片 URL: " + image.getUrl());
}
}

4.2 带参数控制

完整示例:ImageOptionsDemo.java
ImageOptionsDemo.java
@Component
public class ImageOptionsDemo implements CommandLineRunner {

private final ImageModel imageModel;

public ImageOptionsDemo(ImageModel imageModel) {
this.imageModel = imageModel;
}

@Override
public void run(String... args) {
ImageOptions options = ImageOptionsBuilder.builder()
.N(2)
.width(1024)
.height(1024)
.style("vivid")
.build();

ImagePrompt prompt = new ImagePrompt(
"一座建在巨树上的精灵城市,奇幻风格",
options
);

ImageResponse response = imageModel.call(prompt);

for (ImageGeneration gen : response.getResults()) {
System.out.println("URL: " + gen.getOutput().getUrl());
}
}
}

4.3 加权提示词(多段描述)

ImageMessage 的权重参数允许对提示词的不同部分施加不同影响力。权重越高,该段描述越被模型重视。此特性对 Stability AI 尤为关键,DALL-E 权重偏差影响较小但仍可用于逻辑分组。

完整示例:WeightedPromptDemo.java
WeightedPromptDemo.java
@Component
public class WeightedPromptDemo implements CommandLineRunner {

private final ImageModel imageModel;

public WeightedPromptDemo(ImageModel imageModel) {
this.imageModel = imageModel;
}

@Override
public void run(String... args) {
List<ImageMessage> messages = List.of(
new ImageMessage("一只可爱的柯基犬", 2.0f),
new ImageMessage("背景是樱花树下", 0.5f),
new ImageMessage("柔和的光线,浅景深", 0.3f)
);

ImagePrompt prompt = new ImagePrompt(
messages,
ImageOptionsBuilder.builder()
.model("dall-e-3")
.width(1024)
.height(1024)
.build()
);

ImageResponse response = imageModel.call(prompt);
System.out.println("URL: " + response.getResult().getOutput().getUrl());
}
}

5. 便携式选项

ImageOptions 是跨厂商的便携式选项接口,ImageOptionsBuilder 提供链式 API 构建选项。

ImageOptions options = ImageOptionsBuilder.builder()
.model("dall-e-3")
.width(1024)
.height(1024)
.N(1)
.style("vivid")
.build();

ImagePrompt prompt = new ImagePrompt("未来城市", options);

6. 完整综合示例

完整示例:ImageGenerationCompleteExample.java
ImageGenerationCompleteExample.java
@Component
public class ImageGenerationCompleteExample implements CommandLineRunner {

private final ImageModel imageModel;

public ImageGenerationCompleteExample(ImageModel imageModel) {
this.imageModel = imageModel;
}

@Override
public void run(String... args) {
record GenerationResult(String url, String revisedPrompt, Long created) {}

List<ImageMessage> messages = List.of(
new ImageMessage("一个未来科技公司办公室,玻璃幕墙,悬浮办公桌", 1.5f),
new ImageMessage("色调:蓝白为主,配合暖黄灯光", 0.8f)
);

ImageOptions options = ImageOptionsBuilder.builder()
.model("dall-e-3")
.N(1)
.width(1024)
.height(1024)
.style("vivid")
.responseFormat("url")
.build();

ImageResponse response = imageModel.call(new ImagePrompt(messages, options));

for (ImageGeneration gen : response.getResults()) {
Image image = gen.getOutput();
OpenAiImageGenerationMetadata metadata =
(OpenAiImageGenerationMetadata) gen.getMetadata();

System.out.println("图片 URL: " + image.getUrl());
System.out.println("优化提示词: " + metadata.getRevisedPrompt());
}

System.out.println("响应创建时间: " + response.getMetadata().getCreated());
}
}