From 93e9c619438b0ad4c1ddb75a75a4f71e91713833 Mon Sep 17 00:00:00 2001 From: xupei Date: Fri, 20 Sep 2024 11:32:09 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=96=B0=E5=A2=9E=20imageToSketch=20?= =?UTF-8?q?2=E3=80=81=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ai/da/common/config/RedisConfig.java | 27 -- .../com/ai/da/common/utils/RedisUtil.java | 17 - .../da/controller/DesignDetailController.java | 31 -- .../ai/da/controller/GenerateController.java | 15 + .../ai/da/mapper/primary/UserLikeMapper.java | 9 - .../ai/da/model/dto/GenerateModifyDTO.java | 18 + .../dto/GenerateThroughImageTextDTO.java | 2 +- .../java/com/ai/da/python/PythonService.java | 60 ++- .../com/ai/da/service/DesignItemService.java | 12 - .../com/ai/da/service/GenerateService.java | 5 + .../service/impl/DesignItemServiceImpl.java | 384 +----------------- .../da/service/impl/GenerateServiceImpl.java | 106 +++-- .../impl/SuperResolutionServiceImpl.java | 1 - 13 files changed, 181 insertions(+), 506 deletions(-) create mode 100644 src/main/java/com/ai/da/model/dto/GenerateModifyDTO.java diff --git a/src/main/java/com/ai/da/common/config/RedisConfig.java b/src/main/java/com/ai/da/common/config/RedisConfig.java index 611df6b6..5f01753c 100644 --- a/src/main/java/com/ai/da/common/config/RedisConfig.java +++ b/src/main/java/com/ai/da/common/config/RedisConfig.java @@ -39,31 +39,4 @@ public class RedisConfig { redisTemplate.afterPropertiesSet(); return redisTemplate; } - - // todo delete - @Bean(name = "redisListTemplate") - public RedisTemplate getRedisListTemplate(RedisConnectionFactory factory) { - RedisTemplate redisListTemplate = new RedisTemplate<>(); - redisListTemplate.setConnectionFactory(factory); - - StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); - - redisListTemplate.setKeySerializer(stringRedisSerializer); // key的序列化类型 - - Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); - // 方法过期,改为下面代码 -// objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); - objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, - ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); - jackson2JsonRedisSerializer.setObjectMapper(objectMapper); - jackson2JsonRedisSerializer.setObjectMapper(objectMapper); - - redisListTemplate.setValueSerializer(jackson2JsonRedisSerializer); // value的序列化类型 - redisListTemplate.setHashKeySerializer(stringRedisSerializer); - redisListTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); - redisListTemplate.afterPropertiesSet(); - return redisListTemplate; - } } diff --git a/src/main/java/com/ai/da/common/utils/RedisUtil.java b/src/main/java/com/ai/da/common/utils/RedisUtil.java index c3e71cb3..d6e5c100 100644 --- a/src/main/java/com/ai/da/common/utils/RedisUtil.java +++ b/src/main/java/com/ai/da/common/utils/RedisUtil.java @@ -21,10 +21,6 @@ public class RedisUtil { @Resource private RedisTemplate redisTemplate; - // todo delete - @Resource - private RedisTemplate>> redisListTemplate; - public Boolean hasKey(String key){ return redisTemplate.hasKey(key); } @@ -232,17 +228,4 @@ public class RedisUtil { return redisTemplate.opsForValue().increment(key, 0); } - // todo delete - public final static String NO_GRADIENT = "NoGradient"; - public final static String NO_GRADIENT_MASK = "MaskConvert:NoGradient"; - public final static String WITH_GRADIENT = "WithGradient"; - public final static String WITH_GRADIENT_MASK = "MaskConvert:WithGradient"; - public void addToStringList(String key, List> list){ - redisListTemplate.opsForValue().set(key, list); - } - - public List> getFromStringList(String key){ - return redisListTemplate.opsForValue().get(key); - } - } diff --git a/src/main/java/com/ai/da/controller/DesignDetailController.java b/src/main/java/com/ai/da/controller/DesignDetailController.java index d3ab5a0f..994b0b2c 100644 --- a/src/main/java/com/ai/da/controller/DesignDetailController.java +++ b/src/main/java/com/ai/da/controller/DesignDetailController.java @@ -81,14 +81,6 @@ public class DesignDetailController { return Response.success(designItemService.editLayersPositionAndScale(positionAndScaleVO)); } - // todo delete - @ApiOperation(value = "按是否使用了渐变色对历史like进行分类") - @GetMapping("/classificationByGradientColor") - public Response classificationByGradientColor(){ - designItemService.classificationByGradientColor(); - return Response.success("success"); - } - @ApiOperation(value = "mask数据兼容") @GetMapping("/convertWithoutGradient") public Response convertHistoryMaskWithoutGradient(){ @@ -102,27 +94,4 @@ public class DesignDetailController { designItemService.updateMaskUrl(); return Response.success("success"); } - - // todo delete - @ApiOperation(value = "获取历史like中包含有渐变色的design") - @GetMapping("/getHistoryLikeWithGradient") - public Response>> getHistoryLikeWithGradient(){ - return Response.success(designItemService.getHistoryLikeWithGradient()); - } - - // todo delete - @ApiOperation(value = "删除没有model的designItem") - @GetMapping("/deleteNotFoundModelDesign") - public Response deleteNotFoundModelDesign(){ - designItemService.deleteNotFoundModelDesign(); - return Response.success("success"); - } - - // todo delete - @ApiOperation(value = "单个design 有渐变色的mask替换") - @PostMapping("/designSingleWithGradient") - public Response designSingleWithGradient(@Valid @RequestBody DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO) { - designItemService.designSingleWithGradient(designSingleIncludeLayersDTO); - return Response.success("success"); - } } diff --git a/src/main/java/com/ai/da/controller/GenerateController.java b/src/main/java/com/ai/da/controller/GenerateController.java index caa80dcc..5ea57c2c 100644 --- a/src/main/java/com/ai/da/controller/GenerateController.java +++ b/src/main/java/com/ai/da/controller/GenerateController.java @@ -2,6 +2,7 @@ package com.ai.da.controller; import com.ai.da.common.response.Response; import com.ai.da.model.dto.GenerateLikeDTO; +import com.ai.da.model.dto.GenerateModifyDTO; import com.ai.da.model.dto.GenerateThroughImageTextDTO; import com.ai.da.model.vo.*; import com.ai.da.service.GenerateService; @@ -83,5 +84,19 @@ public class GenerateController { return Response.success(generateResult); } + @ApiOperation(value = "imageToSketch") + @PostMapping("/imageToSketch") + public Response imageToSketch(@Valid @RequestBody GenerateThroughImageTextDTO generateThroughImageTextDTO) { + String generateResult = generateService.imageToSketch(generateThroughImageTextDTO); + return Response.success(generateResult); + } + + // modifySketch + @ApiOperation(value = "modifySketch") + @PostMapping("/modifySketch") + public Response modifySketch(@Valid @RequestBody GenerateModifyDTO generateModifyDTO) { + generateService.modifySketch(generateModifyDTO); + return Response.success("success"); + } } diff --git a/src/main/java/com/ai/da/mapper/primary/UserLikeMapper.java b/src/main/java/com/ai/da/mapper/primary/UserLikeMapper.java index 35c79ef2..34e7a0d1 100644 --- a/src/main/java/com/ai/da/mapper/primary/UserLikeMapper.java +++ b/src/main/java/com/ai/da/mapper/primary/UserLikeMapper.java @@ -14,13 +14,4 @@ import java.util.Map; */ public interface UserLikeMapper extends CommonMapper { - // todo delete - List> getHistoryLikeWithoutGradient(); - - // todo delete - List> getHistoryLikeWithGradient(); - - // todo delete - List> getHistoryLikeWithoutModel(); - } diff --git a/src/main/java/com/ai/da/model/dto/GenerateModifyDTO.java b/src/main/java/com/ai/da/model/dto/GenerateModifyDTO.java new file mode 100644 index 00000000..5cc4a77f --- /dev/null +++ b/src/main/java/com/ai/da/model/dto/GenerateModifyDTO.java @@ -0,0 +1,18 @@ +package com.ai.da.model.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@ApiModel("修改imageToSketch提取出的sketch") +@Data +public class GenerateModifyDTO { + @ApiModelProperty("需要保存的图片的base64格式") + private String base64; + + @ApiModelProperty("sketch所属性别") + private String gender; + + @ApiModelProperty("sketch所属分类") + private String category; +} diff --git a/src/main/java/com/ai/da/model/dto/GenerateThroughImageTextDTO.java b/src/main/java/com/ai/da/model/dto/GenerateThroughImageTextDTO.java index 6320dd5d..8dbeca50 100644 --- a/src/main/java/com/ai/da/model/dto/GenerateThroughImageTextDTO.java +++ b/src/main/java/com/ai/da/model/dto/GenerateThroughImageTextDTO.java @@ -25,7 +25,7 @@ public class GenerateThroughImageTextDTO { @ApiModelProperty("text image text-image") String generateType; - @ApiModelProperty("图片是update,还是从library中选择 collection || library") + @ApiModelProperty("图片来源:update,从library中选择,从toProductImage结果中选择 collection || library || productImage") String designType; @NotBlank(message = "level1Type cannot be empty!") diff --git a/src/main/java/com/ai/da/python/PythonService.java b/src/main/java/com/ai/da/python/PythonService.java index f7929504..9b8e6186 100644 --- a/src/main/java/com/ai/da/python/PythonService.java +++ b/src/main/java/com/ai/da/python/PythonService.java @@ -2643,8 +2643,6 @@ public class PythonService { minioPath = minioUtil.base64UploadToPath(colorImg, gradientBucketName, null); designSingleItem.getGradient().setColorImg(null); gradientString = JSONObject.toJSONString(designSingleItem.getGradient()); - - // todo 当渐变色不为空时,是否需要将颜色置为 0 0 0 } PrintToPython printToPython = resolveDesignSinglePrint(designSingleItem.getPrintObject().getPrints()); @@ -3450,4 +3448,62 @@ public class PythonService { //生成失败 throw new BusinessException("relightImage.interface.exception"); } + + public String imageToSketch(String imagePath, String bucket, String objectName){ + OkHttpClient client = new OkHttpClient().newBuilder() + .connectTimeout(30, TimeUnit.SECONDS) + .pingInterval(5, TimeUnit.SECONDS)//websocket轮训间隔(单位:秒) + .readTimeout(60, TimeUnit.SECONDS)//读取超时(单位:秒) + .writeTimeout(60, TimeUnit.SECONDS)//写入超时(单位:秒) + .build(); + MediaType paramMap = MediaType.parse("application/json"); + //关闭FastJson的引用检测 防止出现$ref 现象 + Map map = new HashMap<>(); + map.put("image_url", imagePath); + map.put("sketch_bucket", bucket); + map.put("sketch_name", objectName); + + log.info("ImageToSketch请求python 参数:####{}", map); + String param = JSON.toJSONString(map, SerializerFeature.WriteNullStringAsEmpty); + RequestBody body = RequestBody.create(paramMap, param); + Request request = new Request.Builder() + .url(accessPythonIp + ":" + accessPythonPort + "/api/image2sketch") + .method("POST", body) + .addHeader("Authorization", "Basic YWlkbGFiOjEyMw==") + .addHeader("Content-Type", "application/json") + .build(); + Response response; + + try { + response = client.newCall(request).execute(); + } catch (IOException ioException) { + log.error("PythonService##ImageToSketch异常###{}", ExceptionUtil.getThrowableList(ioException)); + throw new BusinessException("generate.interface.error"); + } + int responseCode = response.code(); + String bodyString; + try { + bodyString = response.body().string(); + if (responseCode != HttpURLConnection.HTTP_OK) { + // 基本不会有除200以外的code + log.info("ImageToSketch 失败。 Response code {}", responseCode); + throw new BusinessException("ImageToSketch 失败。 Response code " + responseCode); + } + JSONObject jsonObject = JSON.parseObject(bodyString); + if (response.isSuccessful() && jsonObject.get("msg").equals("OK!")) { + String sketchResult = jsonObject.get("data").toString(); + log.info("ImageToSketch 结果 : {}", sketchResult); + return sketchResult; + }else { + log.info("ImageToSketch 失败。 Response code {}", responseCode); + throw new BusinessException("ImageToSketch 失败。 Response code " + responseCode); + } + } catch (IOException e) { + log.error("ImageToSketch 失败; error message => {}", e.getMessage()); + response.close(); + throw new BusinessException("generate.interface.error"); + } finally { + response.close(); + } + } } diff --git a/src/main/java/com/ai/da/service/DesignItemService.java b/src/main/java/com/ai/da/service/DesignItemService.java index b9392bd2..fcc1e78b 100644 --- a/src/main/java/com/ai/da/service/DesignItemService.java +++ b/src/main/java/com/ai/da/service/DesignItemService.java @@ -61,19 +61,7 @@ public interface DesignItemService extends IService { Long getCountByUserAndTime(String startTime, String endTime, List accountIds); - // todo delete - void classificationByGradientColor(); - - // todo delete - List> getHistoryLikeWithGradient(); - void convertHistoryMaskWithoutGradient(); void updateMaskUrl(); - - // todo delete - void deleteNotFoundModelDesign(); - - // todo delete - void designSingleWithGradient(DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO); } diff --git a/src/main/java/com/ai/da/service/GenerateService.java b/src/main/java/com/ai/da/service/GenerateService.java index f1f219aa..36e028f2 100644 --- a/src/main/java/com/ai/da/service/GenerateService.java +++ b/src/main/java/com/ai/da/service/GenerateService.java @@ -3,6 +3,7 @@ package com.ai.da.service; import com.ai.da.mapper.primary.entity.Generate; import com.ai.da.mapper.primary.entity.GenerateDetail; import com.ai.da.model.dto.GenerateLikeDTO; +import com.ai.da.model.dto.GenerateModifyDTO; import com.ai.da.model.dto.GenerateThroughImageTextDTO; import com.ai.da.model.vo.*; import com.baomidou.mybatisplus.extension.service.IService; @@ -41,4 +42,8 @@ public interface GenerateService extends IService { void processRelightResult(String taskId, String url, String category); List> getCountByUserAndTime(String startTime, String endTime, List accountIdList); + + String imageToSketch(GenerateThroughImageTextDTO generateThroughImageTextDTO); + + void modifySketch(GenerateModifyDTO generateModifyDTO); } diff --git a/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java b/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java index de578c4a..c8180384 100644 --- a/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/DesignItemServiceImpl.java @@ -928,80 +928,6 @@ public class DesignItemServiceImpl extends ServiceImpl> noGradientList = new ArrayList<>(); - List> withGradientList = new ArrayList<>(); - List> duplicateGradientList = new ArrayList<>(); - - // 1、获取t_user_like表中design_item_id不为-1的所有design_item_id, design_outfit_id - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.ne("design_item_id", -1); - queryWrapper.ne("converted", 1); - - List userLikes = userLikeMapper.selectList(queryWrapper); - log.info("userLike 总数 :{}", userLikes.size()); - - long start = System.currentTimeMillis(); - // 2、遍历每个design_item_id - try { - userLikes.forEach(userLike -> { - log.info("user_like_id:{}, design_item_id:{}, design_python_outfit_id:{}", userLike.getId(), userLike.getDesignItemId(), userLike.getDesignOutfitId()); - List designItemDetails = designItemDetailService.selectByDesignItemId(userLike.getDesignItemId()); - if (designItemDetails.isEmpty()){ - log.error("无法找到history中的被like的design item => design_item_id : {}", userLike.getDesignItemId()); - }else { - boolean flag = true; - for (DesignItemDetail designItemDetail : designItemDetails) { - if (!designItemDetail.getType().equals("Body") && !StringUtils.isNullOrEmpty(designItemDetail.getGradientString())) { - flag = false; - break; - } - } - List list = Arrays.asList(userLike.getDesignItemId(), userLike.getDesignOutfitId()); - if (flag){ - // 如果design_item_id对应的每个单品都没有使用渐变色,则将该design_item_id noGradientList - if (!noGradientList.contains(list)){ - noGradientList.add(list); - }else { - duplicateGradientList.add(list); - } - }else { - // 如果design_item_id对应的任一个单品使用了渐变色,则将该design_item_id design_python_outfit_id加入withGradientList - if (!withGradientList.contains(list)){ - withGradientList.add(list); - }else { - duplicateGradientList.add(list); - } - } - } - }); - }catch (Exception e){ - log.error(e.getMessage()); - } - - long end = System.currentTimeMillis(); - log.info("按是否使用了渐变色对历史like进行分类 执行时长:{}毫秒", end - start); - - // 3、将分类好的数据存入redis中 -// redisUtil.addToStringList(RedisUtil.NO_GRADIENT, noGradientList); -// redisUtil.addToStringList(RedisUtil.WITH_GRADIENT, withGradientList); - redisUtil.addToStringList(RedisUtil.NO_GRADIENT_MASK, noGradientList); - redisUtil.addToStringList(RedisUtil.WITH_GRADIENT_MASK, withGradientList); - - log.info("从t_user_like表,通过渐变色分类,完成,其中总like量为:{}, 没有使用渐变色的like量为:{}, 使用了渐变色的like量为:{}", userLikes.size(), noGradientList.size(), withGradientList.size()); - log.info("使用了渐变色的like: {}", withGradientList); - log.info("未使用渐变色的like: {}", noGradientList); - log.info("重复的like: {},总数:{}", duplicateGradientList, duplicateGradientList.size()); - - } - - // todo delete - public List> getHistoryLikeWithGradient(){ - return redisUtil.getFromStringList(RedisUtil.WITH_GRADIENT); - } - @Resource private UserLikeMapper userLikeMapper; @@ -1027,13 +953,15 @@ public class DesignItemServiceImpl extends ServiceImpl> groupedData = new HashMap<>(); Long designItemId = item.getDesignItemId(); Long designOutfitId = item.getDesignOutfitId(); -// Long designItemId = (long)item.get("design_item_id"); -// Long designOutfitId = (long)item.get("design_outfit_id"); List designPythonOutfitDetails = designPythonOutfitDetailService.getDetailByDesignPythonOutfitId(designOutfitId); List designItemDetails = designItemDetailService.selectByDesignItemId(designItemId); + // 为没有优先级的sketch添加优先级 designItemDetailService.setDesignItemDetailPriority(designItemDetails); + // 为没有优先级的图层添加优先级 + designPythonOutfitDetailService.setDesignPythonOutfitDetailPriority(designPythonOutfitDetails); Map designItemPath = designItemDetails.stream() + .filter(designItemDetail -> !designItemDetail.getType().equals("Body")) .collect(Collectors.toMap( DesignItemDetail::getPriority, // key: category 转为小写 DesignItemDetail::getPath // value: path 字段 @@ -1082,83 +1010,6 @@ public class DesignItemServiceImpl extends ServiceImpl> historyLikeWithoutGradient = redisUtil.getFromStringList(RedisUtil.NO_GRADIENT); - log.info("historyLikeWithoutGradient total count : {}", historyLikeWithoutGradient.size()); - // 遍历list - long start = System.currentTimeMillis(); - int count = 0; - try { - List> errorConvertedList = new ArrayList<>(); - for (int i = 45; i < 50; i++){ - List userLikeMap = historyLikeWithoutGradient.get(i); - log.info("test 替换mask{}", userLikeMap.toString()); - Long designItemId = userLikeMap.get(0); - Long designOutfitId = userLikeMap.get(1); - - // 1、查询design_item_id和design_python_outfit_id对应的accountId - List userLikeList = getUserLikeByDesignItemId(designItemId, designOutfitId); - // 如果已经替换了新的mask则直接跳过 - if (userLikeList.get(0).getConverted() == 1){ - log.info("designItemId: {}, designOutfitId : {} mask已替换", designItemId, designOutfitId); - continue; - } - UserLikeGroup userLikeGroup = userLikeGroupService.getById(userLikeList.get(0).getUserLikeGroupId()); - if (userLikeGroup == null) { - log.error("在t_user_like_group表中找不到id为:{} 的记录", userLikeList.get(0).getUserLikeGroupId()); - errorConvertedList.add(Arrays.asList(designItemId, designOutfitId)); - continue; - } - - // 2、查每个design_item_id和design_python_outfit_id的detail - long startDetail = System.currentTimeMillis(); - DesignItemDetailVO detail = designService.detail(designOutfitId, designItemId); - long endDetail = System.currentTimeMillis(); - log.info("查询design detail 执行时长:{}毫秒", endDetail - startDetail); - - Long accountId = userLikeGroup.getAccountId(); - // 3、组装参数 - long startConvert = System.currentTimeMillis(); - DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO = convertToDesignSingleIncludeLayersDTO(detail, accountId); - if (Objects.isNull(designSingleIncludeLayersDTO)){ - log.error("cannot find model. designItemId: {}, designOutfitId : {}", designItemId, designOutfitId); - errorConvertedList.add(Arrays.asList(designItemId, designOutfitId)); - continue; - } - long endConvert = System.currentTimeMillis(); - log.info("组装designSingle参数 执行时长:{}毫秒", endConvert - startConvert); - - // 4、调用design single - long startDesignSingle = System.currentTimeMillis(); - designSingleIncludeLayers(designSingleIncludeLayersDTO, accountId); - long endDesignSingle = System.currentTimeMillis(); - log.info("执行designSingle 执行时长:{}毫秒", endDesignSingle - startDesignSingle); - - // 5、标志字段置为1 - for (UserLike item : userLikeList ) { - UserLike userLike = new UserLike(); - userLike.setId(item.getId()); - userLike.setConverted(1); - - userLikeMapper.updateById(userLike); - } - log.info("designItemId: {}, designOutfitId : {} mask替换完成", designItemId, designOutfitId); - count++; - } - List> errorConverted = redisUtil.getFromStringList(RedisUtil.ERROR_CONVERTED); - errorConverted.addAll(errorConvertedList); - redisUtil.addToStringList(RedisUtil.ERROR_CONVERTED, errorConverted); - }catch (Exception e){ - log.error("mask convert error : {}", e.getMessage()); - e.printStackTrace(); - } - long end = System.currentTimeMillis(); - - log.info("convert mask 成功 {}条 执行时长:{}毫秒", count, end - start);*/ - } @Transactional(rollbackFor = Exception.class) @@ -1230,231 +1081,4 @@ public class DesignItemServiceImpl extends ServiceImpl getUserLikeByDesignItemId(Long designItemId, Long designOutfitId){ - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("design_item_id", designItemId); - if (!Objects.isNull(designOutfitId)){ - queryWrapper.eq("design_outfit_id", designOutfitId); - } - - return userLikeMapper.selectList(queryWrapper); - } - - // todo delete - public DesignSingleIncludeLayersDTO convertToDesignSingleIncludeLayersDTO(DesignItemDetailVO designItemDetailVO, Long userId){ - DesignSingleIncludeLayersDTO resp = new DesignSingleIncludeLayersDTO(); - - Long designItemId = designItemDetailVO.getDesignItemId(); - resp.setDesignItemId(designItemId); - resp.setIsPreview(Boolean.FALSE); - resp.setProcessId(String.valueOf(userId)); - resp.setTimeZone("Etc/GMT-8"); - List designSingleItemDTOS = new ArrayList<>(); - resp.setDesignSingleItemDTOList(designSingleItemDTOS); - - designItemDetailVO.getClothes().forEach(cloth -> { - DesignSingleItemDTO itemDTO = CopyUtil.copyObject(cloth, DesignSingleItemDTO.class); - itemDTO.setChanged(Boolean.FALSE); - itemDTO.setDesignType("Library"); - itemDTO.setPath(cloth.getMinIOPath()); - PantoneVO color = cloth.getColor(); - String colorString = color.getR() + " " + color.getG() + " " + color.getB(); - itemDTO.setColor(colorString); - if (cloth.getLayersObject().isEmpty()){ - itemDTO.setOffset(Arrays.asList(0L,0L)); - itemDTO.setScale(new Float[]{1.0f,1.0f}); - }else { - DesignPythonOutfitVO designPythonOutfitVO = cloth.getLayersObject().get(0); - itemDTO.setOffset(designPythonOutfitVO.getOffset()); - itemDTO.setScale(designPythonOutfitVO.getScale()); - } - // 统一设置mask为null,不用旧版mask - itemDTO.setMaskMinioUrl(null); - designSingleItemDTOS.add(itemDTO); - }); - - return resp; - } - - // temp 用于处理历史like的design没有新的mask的问题 - public void designSingleIncludeLayers(DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO, Long userId) { - // 记录入参 base64数据太长,所以这里去掉 - DesignSingleIncludeLayersDTO clone = SerializationUtils.clone(designSingleIncludeLayersDTO); - clone.getDesignSingleItemDTOList().forEach( i -> { - // 渐变色 - if (!Objects.isNull(i.getGradient()) && !StringUtil.isNullOrEmpty(i.getGradient().getColorImg())){ - log.info("set gradient colorImage为空,便于日志打印"); - i.getGradient().setColorImg(null); - } - // 画笔修改过的sketch - if (!StringUtil.isNullOrEmpty(i.getSketchString())){ - log.info("set sketchString为空,便于日志打印"); - i.setSketchString(null); - } - // 标注过的mask - if (!StringUtil.isNullOrEmpty(i.getMaskUrl())){ - log.info("set labelingMask为空,便于日志打印"); - i.setMaskUrl(null); - } - }); - - log.info("designSingle request入参 ==> " + JSONObject.toJSONString(clone)); - - DesignItem designItem = selectById(designSingleIncludeLayersDTO.getDesignItemId()); - if (Objects.isNull(designItem)) { - throw new BusinessException("designItem.not.found"); - } - Design design = designService.getById(designItem.getDesignId()); - if (Objects.isNull(design)) { - throw new BusinessException("design.not.found"); - } - - DesignLibraryModelPointVO designLibraryModelPointVO = null; - // 设置模特 - if (Objects.nonNull(design.getTemplateId())) { - String modelUrl; - Integer high; - Integer width; - if (design.getModelType().equals(ModelType.SYSTEM.getValue())) { - SysFileVO sysFile = sysFileService.getById(design.getTemplateId()); - if (Objects.isNull(sysFile)) { - throw new BusinessException("model.not.found"); - } - modelUrl = sysFile.getUrl(); - high = 700; - width = 320; - designSingleIncludeLayersDTO.setGender(sysFile.getLevel2Type()); - } else if (design.getModelType().equals(ModelType.LIBRARY.getValue())){ - Library libFile = libraryService.getById(design.getTemplateId()); - if (Objects.isNull(libFile)) { - throw new BusinessException("model.not.found"); - } - modelUrl = libFile.getUrl(); - high = libFile.getHigh(); - width = libFile.getWidth(); - designSingleIncludeLayersDTO.setGender(libFile.getLevel2Type()); - }else { - throw new BusinessException("unknown.modelType"); - } - LibraryModelPoint modelPoint = libraryModelPointService.getByRelationId(design.getTemplateId(), design.getModelType()); - if (Objects.isNull(modelPoint)) { - throw new BusinessException("modelPoint.not.found"); - } - - designLibraryModelPointVO = collectionElementService.calculateTemplatePoint(modelPoint, high, width, modelUrl); - } - - // 画笔修改的sketch截图 上传后替换path - // 由于用户在系统或自己上传sketch的基础上修改过的衣服,再次修改后,第一次修改的衣服不会回到某个池子被再次利用, - // 所以,这里选择使用system或collection相同的地址,只是放在不同的桶,这样能保证图片服务器上,类似的sketch不会存在很多 - sketchBase64ToPath(designSingleIncludeLayersDTO); - - // 组装入参 - DesignPythonObjects objects = pythonService.covertDesignSingleParam( - designSingleIncludeLayersDTO, design.getSingleOverall(), design.getSwitchCategory(), designLibraryModelPointVO); - // design - long start = System.currentTimeMillis(); - JSONObject jsonObject = pythonService.designNew(objects); - long end = System.currentTimeMillis(); - log.info("design 执行时长:{}毫秒", end - start); - - JSONObject data = jsonObject.getJSONObject("data"); - if (data == null) { - throw new BusinessException("python response data is null"); - } - JSONObject outfit = data.getJSONObject("0"); - - JSONArray layers = outfit.getJSONArray("layers"); - Map categoryAndUndividedLayer = setTypeAndUndividedLayer(layers); - // 直接更新及保存图层信息,全部走submit 不走preview - saveDesignSingleItemDetailAndLayersCopy(design.getId(), designSingleIncludeLayersDTO.getDesignItemId() - , userId, outfit, designSingleIncludeLayersDTO.getDesignSingleItemDTOList()); - - // 如果当前item被like过,需要更新t_user_like表和t_user_like_group表 - // - 这里,因为处理的都是like过的,所以都需要更新 - updateUserLikeDate(designSingleIncludeLayersDTO.getDesignItemId(),designSingleIncludeLayersDTO.getTimeZone()); - - // 数据替换完成即可,不需要返回数据 - } - - // todo delete - private void saveDesignSingleItemDetailAndLayersCopy(Long designId, Long designItemId, Long userId - , JSONObject outfit, List designSingleItemDTOList) { - - // 6、删除designPythonOutfitDetail表中原始的图层信息(物理删除) - Long designPythonOutfitId = designPythonOutfitService.getByDesignItemId(designItemId).getId(); - designPythonOutfitDetailService.deleteByDesignPythonOutfitIdLogical(designPythonOutfitId); - - // 7、将新生成的图层信息存入designPythonOutfitDetail表 - JSONArray layers = outfit.getJSONArray("layers"); - - Map> priorityOffset = designSingleItemDTOList.stream() - .collect(Collectors.toMap(DesignSingleItemDTO::getPriority, DesignSingleItemDTO::getOffset)); - List list = setTDesignPythonOutfitDetailList(layers, designId, designPythonOutfitId, userId, priorityOffset); - - designPythonOutfitDetailService.saveBatch(list); - } - - // todo delete - public void deleteNotFoundModelDesign(){ - // 查询在user_like的design_item_detail中使用了找不到的model的design_item_id,design_outfit_id有哪些 - List> historyLikeWithoutModel = userLikeMapper.getHistoryLikeWithoutModel(); - List> convertedList = new ArrayList<>(); - for (Map map : historyLikeWithoutModel) { - Long designItemId = map.get("designItemId"); - Long designOutfitId = map.get("designOutfitId"); - convertedList.add(Arrays.asList(designItemId, designOutfitId)); - } - - // 将redis中的这些数据删除,再存回 - List> withGradientList = redisUtil.getFromStringList(RedisUtil.WITH_GRADIENT); - List> noGradientList = redisUtil.getFromStringList(RedisUtil.NO_GRADIENT); - log.info("有渐变色的design item:{},size: {}", withGradientList, withGradientList.size()); - log.info("没有渐变色的design item:{},size: {}", noGradientList, noGradientList.size()); - - withGradientList.removeAll(convertedList); - noGradientList.removeAll(convertedList); - log.info("移除没有model的design后,有渐变色的design item:{},size: {}", withGradientList, withGradientList.size()); - log.info("移除没有model的design后,没有渐变色的design item:{},size: {}", noGradientList, noGradientList.size()); - - redisUtil.addToStringList(RedisUtil.WITH_GRADIENT, withGradientList); - redisUtil.addToStringList(RedisUtil.NO_GRADIENT, noGradientList); - } - - // todo delete - public void designSingleWithGradient(DesignSingleIncludeLayersDTO designSingleIncludeLayersDTO){ - // 1、查询当前design对应mask是否完成了转换 - Long designItemId = designSingleIncludeLayersDTO.getDesignItemId(); - List userLikeList = getUserLikeByDesignItemId(designItemId, null); - Long designOutfitId = userLikeList.get(0).getDesignOutfitId(); - // 如果已经替换了新的mask则直接跳过 - if (userLikeList.get(0).getConverted() == 1){ - log.info("designItemId: {}, designOutfitId : {} mask已替换", designItemId, designOutfitId); - return; - } - UserLikeGroup userLikeGroup = userLikeGroupService.getById(userLikeList.get(0).getUserLikeGroupId()); - if (userLikeGroup == null) { - log.error("在t_user_like_group表中找不到id为:{} 的记录", userLikeList.get(0).getUserLikeGroupId()); - return; - } - - // 查询design_item_id和design_python_outfit_id对应的accountId - Long accountId = userLikeGroup.getAccountId(); - - // 2、执行designSingle - designSingleIncludeLayers(designSingleIncludeLayersDTO, accountId); - - // 5、完成转换的mask, 标志字段置为1 - for (UserLike item : userLikeList ) { - UserLike userLike = new UserLike(); - userLike.setId(item.getId()); - userLike.setConverted(1); - - userLikeMapper.updateById(userLike); - } - log.info("designItemId: {}, designOutfitId : {} mask替换完成", designItemId, designOutfitId); - - } - } diff --git a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java index 95f17e90..17b3ea32 100644 --- a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java @@ -3,14 +3,12 @@ package com.ai.da.service.impl; import com.ai.da.common.config.exception.BusinessException; import com.ai.da.common.constant.CommonConstant; import com.ai.da.common.context.UserContext; -import com.ai.da.common.enums.CollectionLevel2TypeEnum; -import com.ai.da.common.enums.CreditsEventsEnum; -import com.ai.da.common.enums.GenerateModeEnum; -import com.ai.da.common.enums.ModelNameEnum; +import com.ai.da.common.enums.*; import com.ai.da.common.utils.*; import com.ai.da.mapper.primary.*; import com.ai.da.mapper.primary.entity.*; import com.ai.da.model.dto.GenerateLikeDTO; +import com.ai.da.model.dto.GenerateModifyDTO; import com.ai.da.model.dto.GenerateThroughImageTextDTO; import com.ai.da.model.dto.GenerateToPythonDTO; import com.ai.da.model.vo.*; @@ -26,13 +24,16 @@ import com.google.gson.Gson; import io.minio.errors.MinioException; import io.netty.util.internal.StringUtil; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.io.IOException; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.*; import static com.ai.da.common.enums.CollectionLevel1TypeEnum.*; @@ -77,6 +78,9 @@ public class GenerateServiceImpl extends ServiceImpl i @Value("${minio.bucketName.slogan}") private String sloganBucket; + @Value("${minio.bucketName.users}") + private String userBucket; + @Value("${redis.key.relightResultKey}") private String relightResultKey; @@ -88,6 +92,8 @@ public class GenerateServiceImpl extends ServiceImpl i // 创建 Random 对象 Random random = new Random(); + @Autowired + private ProductServiceImpl productServiceImpl; @Override public GenerateCaptionVO generateCaption(Long sketchElementId) { @@ -132,7 +138,6 @@ public class GenerateServiceImpl extends ServiceImpl i text = modifyPrompt(text, generate, generateThroughImageTextDTO.getLevel1Type()); } - // todo 这一步现在还是有必要的吗? // 2.1 sketch或print在t_collection_element表/t_library表中的信息是否需要更新 如 level2Type CollectionElement collectionElement = collectionElementService.editLevel2Type(elementId, generateThroughImageTextDTO.getLevel2Type(), generateThroughImageTextDTO.getDesignType()); @@ -298,27 +303,6 @@ public class GenerateServiceImpl extends ServiceImpl i } generate.setGenerateType(generateType); - /*switch (generateType) { - case "text": - if (StringUtil.isNullOrEmpty(text)) { - throw new BusinessException("please.input.the.caption"); - } - generate.setText(text); - break; - case "image": - if (Objects.isNull(elementId)) { - throw new BusinessException("please.choose.an.image"); - } - generate.setElementId(elementId); - break; - case "text-image": - if (StringUtil.isNullOrEmpty(text) || Objects.isNull(elementId)) { - throw new BusinessException("please.input.the.caption.and.choose.an.image"); - } - generate.setText(text); - generate.setElementId(elementId); - default: - }*/ } private String modifyPrompt(String userInput, Generate generate, String level1Type) { @@ -781,8 +765,78 @@ public class GenerateServiceImpl extends ServiceImpl i @Resource private GenerateMapper generateMapper; + public List> getCountByUserAndTime(String startTime, String endTime, List accountIdList) { List> byTypeAndTime = generateMapper.getByTypeAndTime(startTime, endTime, accountIdList); return byTypeAndTime; } + + @Override + @Transactional(rollbackFor = Exception.class) + public String imageToSketch(GenerateThroughImageTextDTO generateThroughImageTextDTO) { + String bucket = userBucket; + Long accountId = UserContext.getUserHolder().getId(); + + String imagePath; + if (generateThroughImageTextDTO.getDesignType().equals("collection")) { + CollectionElement collectionElement = collectionElementService.getById(generateThroughImageTextDTO.getCollectionElementId()); + imagePath = collectionElement.getUrl(); + } else if (generateThroughImageTextDTO.getDesignType().equals("productImage")) { + ToProductImageResult productImage = toProductImageResultMapper.selectById(generateThroughImageTextDTO.getCollectionElementId()); + imagePath = productImage.getUrl(); + } else { + log.error("unknown designType"); + throw new BusinessException("unknown designType"); + } + log.info(minioUtil.getPreSignedUrl(imagePath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + String imageName = imagePath.substring(imagePath.lastIndexOf("/") + 1); + String objectName = accountId + "/imageToSketch/" + imageName; + String sketchPath = pythonService.imageToSketch(imagePath, bucket, objectName); + + // 存DB + Generate generate = new Generate(); + generate.setAccountId(accountId); + generate.setUniqueId(String.valueOf(0)); + generate.setLevel1Type(SKETCH_BOARD.getRealName()); + generate.setLevel2Type("ImageToSketch"); + generate.setElementSource(generateThroughImageTextDTO.getDesignType()); + generate.setElementId(generateThroughImageTextDTO.getCollectionElementId()); + generate.setGenerateType("image"); + generate.setCreateDate(new Date()); + baseMapper.insert(generate); + + // 返回 + return minioUtil.getPreSignedUrl(sketchPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME); + } + + // 对提取出来的sketch做调整 + // 输入 base64,以及 性别 分类,将图片添加到library + @Override + @Transactional(rollbackFor = Exception.class) + public void modifySketch(GenerateModifyDTO generateModifyDTO) { + log.info("修改提取出的sketch,并加入到library"); + Long accountId = UserContext.getUserHolder().getId(); + String base64 = generateModifyDTO.getBase64(); + String gender = generateModifyDTO.getGender(); + String category = generateModifyDTO.getCategory(); + + // 将base64上传到minio + String path = accountId + "/sketchboard/" + gender.toLowerCase() + "/" + category + "/" + UUID.randomUUID(); + String minioPath = minioUtil.base64UploadToPath(base64, userBucket, path); + + log.info("修改后的图片 : {}", minioPath); + + // 存入db + Library library = new Library(); + library.setAccountId(accountId); + library.setLevel1Type(SKETCH_BOARD.getRealName()); + library.setLevel2Type(category); + library.setLevel3Type(gender); + library.setName(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))); + library.setUrl(minioPath); + library.setMd5(MD5Utils.encryptFile(minioUtil.getPreSignedUrl(minioPath, 24 * 60), Boolean.FALSE)); + library.setCreateDate(new Date()); + + libraryService.save(library); + } } diff --git a/src/main/java/com/ai/da/service/impl/SuperResolutionServiceImpl.java b/src/main/java/com/ai/da/service/impl/SuperResolutionServiceImpl.java index 63585f19..03ed3d69 100644 --- a/src/main/java/com/ai/da/service/impl/SuperResolutionServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/SuperResolutionServiceImpl.java @@ -79,7 +79,6 @@ public class SuperResolutionServiceImpl extends ServiceImpl uuidList = new ArrayList<>(); for (SuperResolutionDTO superResolutionDTO : superResolutionDTOList) { - // todo 校验倍率是否是2的幂次(前端已做) // 2、生成唯一id 使用uuid 由于uuid重复的几率很小很小,故这里取消验证uuid是否已存在 String uuid = UUID.randomUUID().toString();