feat(image): 新增AI相机照片增强处理功能

- 在PipelineScene枚举中新增AI_CAM_ENHANCE场景
- 修改setUserIsBuyItem方法,增加对AI相机照片的图像处理逻辑
- 新增processAiCamImages方法,批量处理AI相机照片
- 新增processSingleAiCamImage方法,处理单张AI相机照片
- 新增buildEnhancerConfig方法,构建图像增强配置
- 实现图像处理管线:下载->超分->增强->上传->清理
- 添加处理结果URL回调更新机制
- 增加异常处理和日志记录,确保处理失败不影响主流程
This commit is contained in:
2025-12-06 16:11:07 +08:00
parent 7749faf807
commit bb71cf9458
3 changed files with 141 additions and 2 deletions

View File

@@ -220,7 +220,7 @@ public class OrderBiz {
break;
case 1: // 视频原素材
case 2: // 照片原素材
case 13: // AI微单
case 13: // AI微单
sourceRepository.setUserIsBuyItem(order.getMemberId(), item.getGoodsType(), item.getGoodsId(), order.getId());
break;
case 3:

View File

@@ -22,7 +22,13 @@ public enum PipelineScene {
* 源图片超分辨率增强场景
* IPC设备拍摄的源图片进行质量提升
*/
SOURCE_PHOTO_SUPER_RESOLUTION("source_photo_sr", "源图片超分辨率增强");
SOURCE_PHOTO_SUPER_RESOLUTION("source_photo_sr", "源图片超分辨率增强"),
/**
* AI相机照片增强场景
* AI相机拍摄的照片进行超分辨率和质量增强
*/
AI_CAM_ENHANCE("ai_cam_enhance", "AI相机照片增强");
private final String code;
private final String description;

View File

@@ -1,10 +1,18 @@
package com.ycwl.basic.repository;
import com.ycwl.basic.image.enhancer.entity.BceEnhancerConfig;
import com.ycwl.basic.image.pipeline.core.PhotoProcessContext;
import com.ycwl.basic.image.pipeline.enums.ImageSource;
import com.ycwl.basic.image.pipeline.enums.ImageType;
import com.ycwl.basic.image.pipeline.enums.PipelineScene;
import com.ycwl.basic.image.pipeline.stages.*;
import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import com.ycwl.basic.pipeline.core.Pipeline;
import com.ycwl.basic.pipeline.core.PipelineBuilder;
import com.ycwl.basic.pricing.dto.VoucherInfo;
import com.ycwl.basic.pricing.enums.VoucherDiscountType;
import com.ycwl.basic.pricing.service.IVoucherService;
@@ -41,9 +49,18 @@ public class SourceRepository {
}
public void setUserIsBuyItem(Long memberId, int type, Long faceId, Long orderId) {
// 如果是AI相机照片类型(type=13),需要进行图像超分和增强处理
boolean needsImageProcessing = (type == 13 || type == 3);
if (type == 13) {
type = 3; // compact
}
// 如果需要图像处理,对该faceId下的所有type=3的照片进行处理
if (needsImageProcessing) {
processAiCamImages(faceId);
}
MemberSourceEntity memberSource = new MemberSourceEntity();
memberSource.setMemberId(memberId);
memberSource.setFaceId(faceId);
@@ -54,6 +71,122 @@ public class SourceRepository {
memberRelationRepository.clearSCacheByFace(faceId);
}
/**
* 处理AI相机照片 - 对照片进行超分辨率和增强处理
*
* @param faceId 人脸ID
*/
private void processAiCamImages(Long faceId) {
try {
// 1. 获取该faceId下所有type=3的照片
List<SourceEntity> aiCamImages = sourceMapper.listAiCamImageByFaceRelation(faceId);
if (aiCamImages == null || aiCamImages.isEmpty()) {
log.info("没有找到需要处理的AI相机照片, faceId: {}", faceId);
return;
}
log.info("开始处理AI相机照片, faceId: {}, 照片数量: {}", faceId, aiCamImages.size());
// 2. 构建图像处理配置
BceEnhancerConfig config = buildEnhancerConfig();
// 3. 为每张照片创建处理管线并执行
for (SourceEntity source : aiCamImages) {
try {
processSingleAiCamImage(source, config);
} catch (Exception e) {
log.error("处理AI相机照片失败, sourceId: {}, error: {}", source.getId(), e.getMessage(), e);
// 继续处理下一张照片,不中断整个流程
}
}
log.info("AI相机照片处理完成, faceId: {}", faceId);
} catch (Exception e) {
log.error("处理AI相机照片整体流程失败, faceId: {}, error: {}", faceId, e.getMessage(), e);
// 即使处理失败也不抛出异常,不影响订单购买流程
}
}
/**
* 处理单张AI相机照片
*
* @param source 原始照片
* @param config 增强配置
*/
private void processSingleAiCamImage(SourceEntity source, BceEnhancerConfig config) {
// 1. 创建处理上下文
PhotoProcessContext context = PhotoProcessContext.builder()
.processId("aicam-" + source.getId())
.originalUrl(source.getUrl())
.scenicId(source.getScenicId())
.imageType(ImageType.NORMAL_PHOTO)
.source(ImageSource.IPC)
.scene(PipelineScene.AI_CAM_ENHANCE)
.build();
context.enableStage("image_sr");
context.enableStage("image_enhance");
// 2. 设置结果URL回调 - 更新source记录
context.setResultUrlCallback(newUrl -> {
SourceEntity updateEntity = new SourceEntity();
updateEntity.setId(source.getId());
updateEntity.setUrl(newUrl);
sourceMapper.update(updateEntity);
log.info("已更新AI相机照片URL, sourceId: {}, oldUrl: {}, newUrl: {}",
source.getId(), source.getUrl(), newUrl);
});
// 3. 构建处理管线: 下载 -> 超分 -> 增强 -> 上传 -> 清理
Pipeline<PhotoProcessContext> pipeline = new PipelineBuilder<PhotoProcessContext>("AiCamEnhancePipeline")
.addStage(new DownloadStage()) // 下载原图
.addStage(new ImageSRStage(config)) // 图像超分辨率
.addStage(new ImageEnhanceStage(config)) // 图像增强
.addStage(new UploadStage()) // 上传处理后的图片
.addStage(new CleanupStage()) // 清理临时文件
.build();
// 4. 执行管线
boolean success = pipeline.execute(context);
if (!success) {
log.warn("AI相机照片处理管线执行失败, sourceId: {}", source.getId());
}
}
/**
* 构建图像增强配置
*
* @return 增强配置
*/
private BceEnhancerConfig buildEnhancerConfig() {
BceEnhancerConfig config = new BceEnhancerConfig();
// 尝试从环境变量读取
String appId = System.getenv("BCE_IMAGE_APP_ID");
String apiKey = System.getenv("BCE_IMAGE_API_KEY");
String secretKey = System.getenv("BCE_IMAGE_SECRET_KEY");
// 如果环境变量没有配置,使用默认值(与PrinterServiceImpl保持一致)
if (appId == null || appId.isBlank()) {
appId = "119554288";
}
if (apiKey == null || apiKey.isBlank()) {
apiKey = "OX6QoijgKio3eVtA0PiUVf7f";
}
if (secretKey == null || secretKey.isBlank()) {
secretKey = "dYatXReVriPeiktTjUblhfubpcmYfuMk";
}
config.setAppId(appId);
config.setApiKey(apiKey);
config.setSecretKey(secretKey);
config.setQps(1.0f);
return config;
}
public void setUserNotBuyItem(Long memberId, int type, Long faceId) {
MemberSourceEntity memberSource = new MemberSourceEntity();
memberSource.setMemberId(memberId);