Java结合大模型文生图实战
Java结合大模型文生图实战
导读:随着AIGC技术的快速发展,文生图已成为软件开发中的热门功能。本文将带你从零开始,使用Java结合OpenAI的DALL-E模型,构建一个完整的文生图系统。
一、技术背景与选型
2023年全球AIGC市场规模达到150亿美元,预计2025年将突破500亿美元。Java作为企业级开发的主力语言,与AI大模型的结合正成为开发者关注的焦点。
为什么选择OpenAI DALL-E?
✅ 技术成熟:API稳定,文档完善✅ 效果优质:生成图片质量高✅ 集成便捷:提供官方Java SDK✅ 商业友好:清晰的定价模型二、系统架构设计
系统架构
六层架构体系:
1️⃣ 表现层:React/Vue前端2️⃣ API网关层:认证授权、流量管理3️⃣ 应用服务层:业务逻辑编排4️⃣ 业务逻辑层:核心算法处理5️⃣ 数据层:MySQL/Redis/MongoDB6️⃣ AI服务层:OpenAI DALL-E调用三、核心代码实现
核心依赖配置
<dependencies> <!-- Spring Boot Webflux --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <!-- OpenAI Client --> <dependency> <groupId>com.theokanning.openai-gpt3-java</groupId> <artifactId>service</artifactId> <version>0.17.0</version> </dependency> <!-- Caffeine缓存 --> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> </dependency></dependencies>核心类图
核心类图
五个核心类:
ImageController:处理HTTP请求 OpenAiImageService:调用OpenAI API ImageRequest:请求参数封装 ImageResponse:响应结果封装 CacheService:缓存管理核心代码示例
ImageRequest - 请求模型
package com.example.textToImage.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import javax.validation.constraints.*;/** * 文生图请求参数 */@Data@NoArgsConstructor@AllArgsConstructorpublic class ImageRequest { /** * 提示词 */ @NotBlank(message = "提示词不能为空") @Size(max = 1000, message = "提示词长度不能超过1000字符") private String prompt; /** * 图片尺寸 */ @NotNull(message = "图片尺寸不能为空") private ImageSize size = ImageSize.S1024X1024; /** * 图片数量 */ @Min(value = 1, message = "图片数量至少为1") @Max(value = 10, message = "图片数量最多为10") private Integer n = 1; /** * 图片风格 */ private ImageStyle style = ImageStyle.VIVID; /** * 用户ID(用于缓存) */ private String userId; /** * 图片尺寸枚举 */ public enum ImageSize { S256X256("256x256"), S512X512("512x512"), S1024X1024("1024x1024"); private final String value; ImageSize(String value) { this.value = value; } public String getValue() { return value; } } /** * 图片风格枚举 */ public enum ImageStyle { NATURAL("natural"), VIVID("vivid"); private final String value; ImageStyle(String value) { this.value = value; } public String getValue() { return value; } }}ImageController - REST接口
package com.example.textToImage.controller;import com.example.textToImage.model.ImageRequest;import com.example.textToImage.model.ImageResponse;import com.example.textToImage.service.OpenAiImageService;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.*;import javax.validation.Valid;import java.util.Arrays;import java.util.List;import java.util.concurrent.CompletableFuture;import java.util.stream.Collectors;/** * 文生图控制器 * * 提供RESTful API接口 */@Slf4j@RestController@RequestMapping("/api/images")@CrossOrigin(origins = "*")public class ImageController { @Autowired private OpenAiImageService imageService; /** * 生成图片 - 同步接口 */ @PostMapping public ResponseEntity<ImageResponse> generateImage(@Valid @RequestBody ImageRequest request) { log.info("收到图片生成请求: prompt={}, size={}", request.getPrompt(), request.getSize()); try { ImageResponse response = imageService.generateImage(request); if (response.getSuccess()) { return ResponseEntity.ok(response); } else { return ResponseEntity.internalServerError().body(response); } } catch (Exception e) { log.error("图片生成请求处理失败", e); return ResponseEntity.internalServerError() .body(ImageResponse.builder() .error(e.getMessage()) .success(false) .build()); } } /** * 生成图片 - 异步接口 */ @PostMapping("/async") public CompletableFuture<ResponseEntity<ImageResponse>> generateImageAsync(@Valid @RequestBody ImageRequest request) { log.info("收到异步图片生成请求: prompt={}", request.getPrompt()); return CompletableFuture.supplyAsync(() -> { try { ImageResponse response = imageService.generateImage(request); if (response.getSuccess()) { return ResponseEntity.ok(response); } else { return ResponseEntity.internalServerError().body(response); } } catch (Exception e) { log.error("异步图片生成请求处理失败", e); return ResponseEntity.internalServerError() .body(ImageResponse.builder() .error(e.getMessage()) .success(false) .build()); } }); } /** * 批量生成图片 */ @PostMapping("/batch") public CompletableFuture<ResponseEntity<List<ImageResponse>>> generateImages( @Valid @RequestBody List<ImageRequest> requests) { return CompletableFuture.supplyAsync(() -> { try { List<ImageResponse> responses = requests.stream() .map(imageService::generateImage) .collect(Collectors.toList()); boolean allSuccess = responses.stream().allMatch(ImageResponse::getSuccess); if (allSuccess) { return ResponseEntity.ok(responses); } else { return ResponseEntity.internalServerError().body(responses); } } catch (Exception e) { log.error("批量图片生成请求处理失败", e); return ResponseEntity.internalServerError() .body(Arrays.asList(ImageResponse.builder() .error(e.getMessage()) .success(false) .build())); } }); } /** * 生成示例图片 */ @GetMapping("/examples") public ResponseEntity<List<ImageRequest>> getExampleRequests() { List<ImageRequest> examples = Arrays.asList( createExampleRequest("一只可爱的卡通猫,坐在花园里,阳光明媚", ImageRequest.ImageSize.S1024X1024, 1, ImageRequest.ImageStyle.VIVID), createExampleRequest("现代城市天际线,夜晚,霓虹灯", ImageRequest.ImageSize.S1024X1024, 1, ImageRequest.ImageStyle.NATURAL), createExampleRequest("抽象艺术,彩色几何形状", ImageRequest.ImageSize.S512X512, 2, ImageRequest.ImageStyle.VIVID) ); return ResponseEntity.ok(examples); } /** * 检查服务状态 */ @GetMapping("/health") public ResponseEntity<String> healthCheck() { return ResponseEntity.ok("Image Generation Service is running"); } /** * 创建请求 */ private ImageRequest createExampleRequest(String prompt, ImageRequest.ImageSize size, int n, ImageRequest.ImageStyle style) { ImageRequest request = new ImageRequest(); request.setPrompt(prompt); request.setSize(size); request.setN(n); request.setStyle(style); return request; }}OpenAiImageService
package com.example.textToImage.service;import com.example.textToImage.model.ApiKeyConfig;import com.example.textToImage.model.ImageRequest;import com.example.textToImage.model.ImageResponse;import com.theokanning.openai.image.CreateImageRequest;import com.theokanning.openai.image.ImageResult;import com.theokanning.openai.service.OpenAiService;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;import java.time.Duration;import java.util.Collections;import java.util.List;import java.util.UUID;import java.util.stream.Collectors;/** * OpenAI文生图服务实现 * * 使用DALL-E 3/2模型生成图片 * 支持多种参数配置 */@Slf4j@Servicepublic class OpenAiImageService { @Autowired private ApiKeyConfig apiKeyConfig; /** * 生成图片 */ @Cacheable(value = "images", key = "#request.prompt + '_' + #request.size + '_' + #request.style") public ImageResponse generateImage(ImageRequest request) { long startTime = System.currentTimeMillis(); String requestId = UUID.randomUUID().toString(); try { // 创建OpenAI服务 OpenAiService service = createOpenAiService(); // 构建请求参数 CreateImageRequest imageRequest = buildCreateImageRequest(request); // 调用API生成图片 ImageResult result = service.createImage(imageRequest); // 构建响应 ImageResponse response = buildResponse(request, requestId, result, startTime); log.info("图片生成成功: requestId={}, prompt={}", requestId, request.getPrompt()); return response; } catch (Exception e) { log.error("图片生成失败: requestId={}, prompt={}", requestId, request.getPrompt(), e); return buildErrorResponse(requestId, e.getMessage(), startTime); } } /** * 创建OpenAI服务 */ private OpenAiService createOpenAiService() { if (apiKeyConfig.getUseProxy() && apiKeyConfig.getProxy() != null) { // 代理配置(示例) return new OpenAiService(apiKeyConfig.getOpenaiKey(), Duration.ofSeconds(apiKeyConfig.getTimeout())); } else { // 直接连接 return new OpenAiService(apiKeyConfig.getOpenaiKey(), Duration.ofSeconds(apiKeyConfig.getTimeout())); } } /** * 构建图片请求 */ private CreateImageRequest buildCreateImageRequest(ImageRequest request) { return CreateImageRequest.builder() .prompt(request.getPrompt()) .n(request.getN()) .size(request.getSize().getValue()) .responseFormat("url") .user(request.getUserId() != null ? request.getUserId() : "anonymous") .build(); } /** * 构建成功响应 */ private ImageResponse buildResponse(ImageRequest request, String requestId, ImageResult result, long startTime) { List<String> urls = Arrays.asList(result.getData().stream() .map(image -> image.getUrl()) .toArray(String[]::new)); List<String> imageIds = Arrays.asList(result.getData().stream() .map(image -> image.getRevisedPrompt() != null ? image.getRevisedPrompt() : "") .toArray(String[]::new)); return ImageResponse.builder() .requestId(requestId) .prompt(request.getPrompt()) .createdAt(java.time.LocalDateTime.now()) .urls(urls) .imageIds(imageIds) .duration(System.currentTimeMillis() - startTime) .success(true) .build(); } /** * 构建错误响应 */ private ImageResponse buildErrorResponse(String requestId, String errorMessage, long startTime) { return ImageResponse.builder() .requestId(requestId) .error(errorMessage) .createdAt(java.time.LocalDateTime.now()) .duration(System.currentTimeMillis() - startTime) .success(false) .build(); }}四、业务流程详解
业务流程详解
8步完整流程:
1️⃣ 用户输入文本:前端提交文本描述2️⃣ 参数验证:校验参数格式和内容3️⃣ 缓存查询:检查是否已生成过4️⃣ 构建API请求:组装OpenAI请求5️⃣ 调用OpenAI:发送图片生成请求6️⃣ 接收响应:获取图片URL7️⃣ 处理结果:保存到数据库8️⃣ 返回图片:响应给用户时序图
时序图
关键交互流程:
前端→控制器:POST请求

控制器→服务:参数验证
服务→缓存:查询缓存
服务→OpenAI:API调用
OpenAI→服务:返回图片URL
服务→缓存:更新缓存
服务→控制器:返回响应
五、缓存机制优化
多级缓存策略
L1 - Caffeine本地缓存
读写速度快,适合热点数据
减少网络调用
L2 - Redis分布式缓存
支持集群,容量大
集群环境数据共享
L3 - OpenAI API缓存
第三方服务自带缓存
降低API成本
Caffeine
@Configuration@EnableCachingpublic class CacheConfig { @Bean public CacheManager cacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeine( Caffeine.newBuilder() .initialCapacity(100) .maximumSize(1000) .expireAfterWrite(1, TimeUnit.HOURS) .recordStats() ); return cacheManager; }}数据流转
数据流转
智能缓存查询流程:
1、用户发起请求2、验证并查询缓存3、缓存未命中调用API4、OpenAI生成图片5、处理结果并缓存6、返回结果给用户六、应用场景实战
电商场景
public ImageResponse generateProductImage(Product product) { String prompt = String.format( "高清商品图,白色背景,产品:%s", product.getName() ); return imageService.generateImage( new ImageRequest(prompt, ImageSize.S1024X1024) );}七、性能优化与部署
部署图
文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有