提示:如果不能访问 OpenAI,请点击 AiCode API 注册账号,通过代理访问。
Spring AI 提供了对图像模型的支持,使用图像模型可生成、分析图像等任务。以下将介绍如何使用 Spring AI 快速调用 OpenAI 的图像模型 dall-e-3(或 dall-e-2)。
DALL-E 是 OpenAI 开发的基于深度学习的图像生成模型,能够根据文本描述生成相应的图像。
DALL-E 是建立在自回归 Transformer 和离散变分自动编码器的基础之上,通过将文本描述映射到语义表示,然后将其转换为图像编码,最终利用扩散生成技术逐步生成图像,从粗略轮廓到精细细节。
DALL-E 的发展历程如下:
DALL-E 1:2021 年 1 月发布,首次实现从文本描述生成图像的功能,能够生成多种风格和形式的图像,基于 GPT-3 的变体,包含 120 亿参数。
DALL-E 2:2022 年 4 月发布,生成的图像更清晰,细节更丰富,引入 “编辑器” 功能,允许对生成的图像进行修改,支持更高分辨率的图像输出。
DALL-E 3:2023 年 9 月发布,内置于 ChatGPT 中,用户可通过对话生成图像,更准确地理解复杂的文本描述,生成更符合预期的图像。2024 年 2 月 7 日,开始为所生成的图像添加来自内容来源和真实性联盟(C2PA)的水印。
在 pom.xml 文件中添加相关依赖,内容如下:
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-model-openai</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai</artifactId> <version>1.0.0</version> </dependency>
在 application.yaml 中配置 API 密钥、基础地址和日志等等,如下:
spring: application: name: springai_demo1 # AI配置 ai: # openai相关配置 openai: # 基础地址 # 访问 https://api.xty.app/register?aff=pO2q 地址注册账号即可访问 OpenAI 了 base-url: https://api.xty.app # AI KEY api-key: sk-vHTHX8D3wNZBfRya****************A23e48AbB600 # 聊天模型配置 chat: options: model: gpt-4-turbo # gpt-3.5-turbo # 图片模型配置 image: options: # 需要高级接口 model: dall-e-3 # 日志配置 logging: charset: console: UTF-8 level: root: info org.springframework.ai: debug
OpenAiImageModel 类实现 ImageModel 接口,提供了调用 OpenAI 图像生成 API 的客户端功能。该类封装了与 OpenAI 图像服务(如 DALL·E 系列、GPT-image-1)的交互逻辑,支持图像生成、编辑和变体生成等操作,并处理了请求参数组装、API 通信及响应解析等底层细节,使开发者能更便捷地集成 OpenAI 图像能力。
例如:根据指令生成一张图片,同时配置图片大小为 1024x1024,生成一张图片。
package com.hxstrive.springai.springai_openai.example.image_model; import org.springframework.ai.image.ImageMessage; import org.springframework.ai.image.ImageOptions; import org.springframework.ai.image.ImagePrompt; import org.springframework.ai.image.ImageResponse; import org.springframework.ai.openai.OpenAiImageModel; import org.springframework.ai.openai.OpenAiImageOptions; import org.springframework.ai.openai.api.OpenAiImageApi; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import java.util.Base64; import java.io.FileOutputStream; import java.io.IOException; @SpringBootApplication public class ImageGenerationExample implements CommandLineRunner { // 在 Spring Boot 中,CommandLineRunner 是一个接口, // 主要作用是在 Spring 容器初始化完成后、应用程序启动过程的最后阶段执行一些特定的代码逻辑。 // 这里使用 CommandLineRunner 接口的 run() 方法去调用生成图片函数, // 避免我们再去编写控制器调用服务,触发图片生成。 // 注入 ImageModel 对象,由 Spring 自动帮我们完成 @Autowired private OpenAiImageModel imageModel; public static void main(String[] args) { SpringApplication.run(ImageGenerationExample.class, args); } @Override public void run(String... args) throws Exception { generateAndSaveImage(); // 生成图像 } /** * 生成AI图像并保存到本地文件 * @throws IOException 当文件操作或图像处理出现错误时抛出 */ private void generateAndSaveImage() throws IOException { System.out.println("AI正在生成图片,请稍后....."); // 创建图像生成的提示信息对象 ImageMessage imageMessage = new ImageMessage("一只戴着太空头盔的可爱猫咪,漂浮在繁星点点的天空中,数字艺术风格。"); // 构建图像生成的配置选项 ImageOptions imageOptions = OpenAiImageOptions.builder() .model("dall-e-3") // 指定使用的AI模型,可以是dall-e-2或dall-e-3 .quality("standard") // 设置图像质量,可选standard(标准)或hd(高清) .width(1024) // 图像宽度,单位像素 .height(1024) // 图像高度,单位像素 .N(1) // 生成的图像数量,这里生成1张 .responseFormat("b64_json") // 响应格式,指定为base64编码的JSON格式 .build(); // 构建配置选项对象 // 创建图像生成请求对象,包含提示信息和配置选项 ImagePrompt imagePrompt = new ImagePrompt(imageMessage, imageOptions); // 调用AI模型生成图像,获取响应结果 ImageResponse imageResponse = imageModel.call(imagePrompt); // 从响应结果中提取base64编码的图像数据 String base64Image = imageResponse.getResult().getOutput().getB64Json(); // 将base64编码的字符串解码为字节数组(图像的二进制数据) byte[] imageBytes = Base64.getDecoder().decode(base64Image); // 使用 try-with-resources 语句创建文件输出流,自动关闭资源 // 将图像字节数据写入文件,保存路径为 D:/generated_cat.png try (FileOutputStream fos = new FileOutputStream("D:/generated_cat.png")) { fos.write(imageBytes); // 写入图像数据 System.out.println("图像已保存为 generated_cat.png"); // 提示保存成功 } } }
运行上述代码,输出图片如下:
在 Spring AI 1.0.0 中,OpenAiImageApi 是对接 OpenAI 图像生成 API 的底层通信层实现,负责处理与 OpenAI 服务的直接 HTTP 交互,是 OpenAiImageModel 的基础依赖。它封装了 OpenAI 图像 API 的原始请求构建、响应解析、异常处理等细节,为上层提供简洁的接口调用能力。
例如:根据指令生成一张图片,同时配置图片大小为 1024x1024,生成一张图片。
AiConfig.java AI配置信息,创建 OpenAiImageApi 对象:
package com.hxstrive.springai.springai_openai.example.image_model2; import org.springframework.ai.model.SimpleApiKey; import org.springframework.ai.model.openai.autoconfigure.OpenAIAutoConfigurationUtil; import org.springframework.ai.model.openai.autoconfigure.OpenAiConnectionProperties; import org.springframework.ai.model.openai.autoconfigure.OpenAiImageProperties; import org.springframework.ai.openai.api.OpenAiImageApi; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.MultiValueMap; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; @Configuration public class AiConfig { @Bean @ConditionalOnMissingBean public OpenAiImageApi openAiImageApi(OpenAiConnectionProperties commonProperties, OpenAiImageProperties imageProperties, ObjectProvider<RestClient.Builder> restClientBuilderProvider, ResponseErrorHandler responseErrorHandler) { // 合并通用配置(commonProperties)和图像专用配置(imageProperties),解决配置冲突(如专用配置优先级高于通用配置) OpenAIAutoConfigurationUtil.ResolvedConnectionProperties resolved = OpenAIAutoConfigurationUtil.resolveConnectionProperties(commonProperties, imageProperties, "image"); MultiValueMap<String, String> headers = resolved.headers(); headers.add("my", "123456"); return OpenAiImageApi.builder() .baseUrl(resolved.baseUrl()) .apiKey(new SimpleApiKey(resolved.apiKey())) .headers(headers) .imagesPath(imageProperties.getImagesPath()) .restClientBuilder((RestClient.Builder)restClientBuilderProvider.getIfAvailable(RestClient::builder)) .responseErrorHandler(responseErrorHandler).build(); } }
ImageGenerationExample.java 示例代码:
package com.hxstrive.springai.springai_openai.example.image_model2; import org.springframework.ai.openai.api.OpenAiImageApi; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.http.HttpStatusCode; import org.springframework.http.ResponseEntity; import org.springframework.util.StringUtils; import java.io.FileOutputStream; import java.io.IOException; import java.util.Base64; import java.util.List; @SpringBootApplication public class ImageGenerationExample implements CommandLineRunner { // 实现CommandLineRunner接口的原因: // 在Spring容器初始化完成后自动执行run()方法,无需编写控制器即可触发图像生成逻辑 // 适合快速演示和测试API功能 /** * 从配置文件读取OpenAI API的基础URL * 默认为空字符串,实际值由 application.yml 中的 spring.ai.openai.base-url 配置 */ @Value("${spring.ai.openai.base-url}") private String baseUrl = ""; /** * 从配置文件读取 OpenAI API 密钥(关键认证信息) * 由 application.yml 中的 spring.ai.openai.api-key 配置,需确保有效 */ @Value("${spring.ai.openai.api-key}") private String apiKey = ""; @Autowired private OpenAiImageApi openAiImageApi; public static void main(String[] args) { SpringApplication.run(ImageGenerationExample.class, args); } /** * CommandLineRunner 接口的实现方法,在应用启动后自动执行 * 这里作为图像生成流程的入口点 * @param args 命令行参数 * @throws Exception 可能抛出的异常(如IO异常、API调用异常等) */ @Override public void run(String... args) throws Exception { // 调用图像生成方法,参数为参考图片URL(本示例中未实际使用该URL,仅作为演示) generateAndSaveImage(); } /** * 生成AI图像并保存到本地文件系统 * 步骤: * 1.构建图像生成请求参数 * 2.调用OpenAI API * 3.处理响应 * 4.保存图像 * @throws IOException 当文件写入或Base64解码失败时抛出 */ private void generateAndSaveImage() throws IOException { System.out.println("正在基于参考图片生成新图片..."); // 构建OpenAI图像生成请求对象 // 参数说明: // 1. prompt: 图像描述文本(核心参数,决定生成内容) // 2. model: 使用的模型(此处为dall-e-3,支持高质量生成) // 3. n: 生成图像数量(dall-e-3仅支持1) // 4. quality: 图像质量(standard/hd,hd为高清) // 5. responseFormat: 响应格式(b64_json表示返回Base64编码) // 6. size: 图像尺寸(1024x1024为正方形标准尺寸) // 7. style: 图像风格(null时使用默认,dall-e-3支持vivid/natural) // 8. user: 关联的用户标识(可选,用于OpenAI的使用跟踪) OpenAiImageApi.OpenAiImageRequest imageRequest = new OpenAiImageApi.OpenAiImageRequest( "生成一张太空猫的图片。", // 文本提示词 "dall-e-3", // 模型名称 1, // 生成数量 "standard", // 图像质量 "b64_json", // 响应格式(Base64) "1024x1024", // 图像尺寸 null, // 风格(使用默认) null // 用户标识(未指定) ); // 调用 OpenAiImageApi 的 createImage 方法,发送生成请求 // 返回值为 ResponseEntity,包含 HTTP 状态码和响应体 ResponseEntity<OpenAiImageApi.OpenAiImageResponse> response = openAiImageApi.createImage(imageRequest); // 获取HTTP响应状态码,判断请求是否成功 HttpStatusCode statusCode = response.getStatusCode(); if (statusCode.is2xxSuccessful()) { // 请求成功:解析响应体获取图像数据 OpenAiImageApi.OpenAiImageResponse imageResponse = response.getBody(); // 获取图像数据列表(由于n=1,列表长度为1) List<OpenAiImageApi.Data> dataList = imageResponse.data(); // 遍历图像数据列表(此处实际仅处理一张图片) for (int i = 0; i < dataList.size(); i++) { OpenAiImageApi.Data data = dataList.get(i); // 调用保存方法,将Base64编码的图像保存为本地文件 saveImage(data.b64Json(), "D:/output-" + i + ".png"); } } else { // 请求失败:输出错误提示 System.out.println("生成图片失败,HTTP状态码:" + statusCode); } } /** * 将Base64编码的图像数据解码并保存为本地PNG文件 * @param imageBase64 图像的Base64编码字符串(由OpenAI API返回) * @param outputImagePath 保存文件的完整路径(如D:/image.png) * @throws IOException 当文件输出流操作失败时抛出 */ private void saveImage(String imageBase64, String outputImagePath) throws IOException { // 检查Base64字符串是否有效(非空且有内容) if (StringUtils.hasText(imageBase64)) { // 解码Base64字符串为字节数组(图像原始数据) byte[] imageBytes = Base64.getDecoder().decode(imageBase64); // 使用try-with-resources语法创建文件输出流,自动关闭资源 try (FileOutputStream fos = new FileOutputStream(outputImagePath)) { fos.write(imageBytes); // 将字节数组写入文件 } // 输出保存成功的信息 System.out.println("新图片已生成并保存至: " + outputImagePath); } else { System.out.println("无效的Base64图像数据,无法保存"); } } }
运行上述代码,输出图片如下:
更多信息参考官方文档 https://docs.spring.io/spring-ai/reference/api/image/openai-image.html。
提示:如果不能访问 OpenAI,请点击 AiCode API 注册账号,通过代理访问。