Spring-ai-alibaba文生图

文章目录

Spring AI Alibaba 图像模型实战(文生图)

用 Spring AI Alibaba 接入阿里云百炼 DashScope,完成「文字 → 图片」。

版本

  • Spring Boot:3.4.5
  • spring-ai-alibaba-starter-dashscope:1.0.0.4
  • Java:17

Spring-ai更新速度快,请以官方为准

可参考网址:

一、依赖引入

xml 复制代码
<!-- Spring Web,提供 REST 接口 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring AI Alibaba:自动装配 DashScopeImageModel -->
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
    <version>1.0.0.4</version>
</dependency>

<!-- 官方 DashScope SDK(部分场景会用到) -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dashscope-sdk-java</artifactId>
    <version>2.22.18</version>
</dependency>

二、yml 配置

yaml 复制代码
# 复制为 application.yaml;密钥用环境变量,不要写死在仓库里
spring:
  application:
    name: spring-image-demo
  ai:
    dashscope:
      # IDEA Run Configuration → Environment:DASHSCOPE_API_KEY=sk-xxx
      api-key: ${DASHSCOPE_API_KEY}
      image:
        options:
          # DashScopeImageModel 兼容的万相文生图模型
          # 不要用 qwen-image-* 等多模态同步模型,会报 url error / 400
          model: wanx2.1-t2i-turbo

启动前设置环境变量:

powershell 复制代码
$env:DASHSCOPE_API_KEY="你的百炼API Key"

三、代码案例

1. 控制器:注入 ImageModel,三种接口

java 复制代码
@RestController
@RequestMapping("/example")
public class DashScopeImageController {

    /** 由 starter 自动配置注入(底层是 DashScopeImageModel) */
    private final ImageModel imageModel;

    private static final String DEFAULT_PROMPT = "为人工智能生成一张富有科技感的图片!";

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

    /**
     * 最简文生图:用默认 prompt 生成一张图,把远端 URL 的字节写回浏览器。
     * GET /example/image
     */
    @GetMapping("/image")
    public void image(HttpServletResponse response) {
        // 1)构造 ImagePrompt(只有提示词,模型走 yml 默认配置)
        ImageResponse imageResponse = imageModel.call(new ImagePrompt(DEFAULT_PROMPT));

        // 2)异步任务完成后,结果里一般是临时图片 URL
        String imageUrl = imageResponse.getResult().getOutput().getUrl();

        try {
            // 3)服务端打开 URL,把 PNG 字节写给前端(浏览器直接显示图片)
            URL url = URI.create(imageUrl).toURL();
            InputStream in = url.openStream();
            response.setHeader("Content-Type", MediaType.IMAGE_PNG_VALUE);
            response.getOutputStream().write(in.readAllBytes());
            response.getOutputStream().flush();
        } catch (IOException e) {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 同一 prompt 生成多张图,返回 URL 集合。
     * GET /example/image/multiPrompt?prompt=一只会编程的猫&count=2
     */
    @GetMapping("/image/multiPrompt")
    public ResponseEntity<Collection<String>> generateImageWithMultiPrompt(
            @RequestParam(value = "prompt", defaultValue = "一只会编程的猫") String prompt,
            @RequestParam(defaultValue = "2") int count) {

        // N:一次要几张图
        ImageOptions options = ImageOptionsBuilder.builder()
                .N(count)
                .build();

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

        // 每张结果取 URL,收集成 Set
        Set<String> imageSet = response.getResults().stream()
                .map(result -> result.getOutput().getUrl())
                .collect(Collectors.toSet());
        return ResponseEntity.ok(imageSet);
    }

    /**
     * 多条件拼 prompt + 宽高。
     * GET /example/image/multipleConditions?subject=猫&environment=办公室&style=生动
     */
    @GetMapping("/image/multipleConditions")
    public ResponseEntity<?> multipleConditions(
            @RequestParam(value = "subject", defaultValue = "一只会编程的猫") String subject,
            @RequestParam(value = "environment", defaultValue = "办公室") String environment,
            @RequestParam(value = "height", defaultValue = "1024") Integer height,
            @RequestParam(value = "width", defaultValue = "1024") Integer width,
            @RequestParam(value = "style", defaultValue = "生动") String style) {

        // 把多个参数拼成一句完整提示词
        String prompt = String.format(
                "一个%s,置身于%s的环境中,使用%s的艺术风格,高清4K画质,细节精致",
                subject, environment, style
        );

        ImageOptions options = ImageOptionsBuilder.builder()
                .height(height)
                .width(width)
                .build();

        try {
            ImageResponse response = imageModel.call(new ImagePrompt(prompt, options));
            // 成功时直接返回图片 URL 字符串
            return ResponseEntity.ok(response.getResult().getOutput().getUrl());
        } catch (Exception e) {
            // 失败时返回 JSON 错误信息,避免空白 500
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(Map.of(
                            "error", "图像生成失败",
                            "message", e.getMessage(),
                            "timestamp", LocalDateTime.now()
                    ));
        }
    }
}

2.(可选)图片未完成时的重试

万相文生图是异步任务。旧版在 pending 时可能抛 RuntimeException,默认 Retry 可能不够。可提供自定义 RetryTemplate

java 复制代码
@Configuration
public class ImageRetryConfig {

    @Bean
    @Primary
    RetryTemplate imageRetryTemplate() {
        return RetryTemplate.builder()
                .maxAttempts(30) // 最多重试次数
                // 初始间隔 2s,倍率 1.5,上限 15s
                .exponentialBackoff(Duration.ofSeconds(2), 1.5, Duration.ofSeconds(15))
                .retryOn(RuntimeException.class)
                .build();
    }
}

注意:HTTP 401(Key 无效)、400(参数错误)属于不可恢复错误,靠加长重试解决不了。

相关推荐
字节数据平台37 分钟前
iDA:从 ChatBI 到专业数据分析助手的演进之路
大数据·人工智能·机器学习·数据分析
warpdrivelabs1 小时前
Codex 开源 harness 全面了解
开发语言·人工智能
mit6.8241 小时前
微软如何交付企业级Agent
人工智能
Mininglamp_27181 小时前
明略科技携手海康机器人亮相世界机器人大会,以“Agent+具身“联合进入商业机器人场景
人工智能·科技·机器人·开源·agent·ai agent
2401_894915531 小时前
GEO 优化源码全解析:从搜索引擎到 AI 引擎的底层改写逻辑
java·服务器·前端·数据库·人工智能·分布式·搜索引擎
MobotStone2 小时前
从“听得懂”到“干得了”:工业大模型落地工厂的三层进化路线
人工智能
wangruofeng3 小时前
GLM-5.3-Flash 发布:追平 Opus 4.8 的智力,1/40 的价格,跑在国产芯片上
人工智能·aigc·chatglm (智谱)
Java牛马5 小时前
SpringBoot Starter 依赖相关总结
java·spring·springboot·starter·自动装配·依赖
皮皮虾❀5 小时前
钉钉AI服务商×教育行业:AI现代产业学院共建一体化实战——从“高校AI教学缺平台”到“校企共建AI产业学院培养数字化人才
人工智能·钉钉
吴声子夜歌5 小时前
Java面试——Spring Cloud原理及应用(二)
java·spring cloud·面试