You've already forked FrameTour-BE
feat(image): 新增AI相机照片增强处理功能
- 在PipelineScene枚举中新增AI_CAM_ENHANCE场景 - 修改setUserIsBuyItem方法,增加对AI相机照片的图像处理逻辑 - 新增processAiCamImages方法,批量处理AI相机照片 - 新增processSingleAiCamImage方法,处理单张AI相机照片 - 新增buildEnhancerConfig方法,构建图像增强配置 - 实现图像处理管线:下载->超分->增强->上传->清理 - 添加处理结果URL回调更新机制 - 增加异常处理和日志记录,确保处理失败不影响主流程
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user