Spring AI 图像模型

提示:如果不能访问 OpenAI,请点击 AiCode API 注册账号,通过代理访问。  

Spring AI 提供了对图像模型的支持,使用图像模型可生成、分析图像等任务。以下将介绍如何使用 Spring AI 快速调用 OpenAI 的图像模型 dall-e-3(或 dall-e-2)。

  

DALL-E 模型介绍

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 生成图片

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 图像模型

使用 OpenAiImageApi 生成图片

在 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图像数据,无法保存");
        }
    }

}

运行上述代码,输出图片如下:

Spring AI 图像模型

更多信息参考官方文档 https://docs.spring.io/spring-ai/reference/api/image/openai-image.html

  

提示:如果不能访问 OpenAI,请点击 AiCode API 注册账号,通过代理访问。  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号