|
|
|
@ -106,24 +106,18 @@ public class StableDiffusionServiceImpl implements StableDiffusionService { |
|
|
|
AiartClient client = new AiartClient(cred, "ap-guangzhou", clientProfile); |
|
|
|
// 实例化一个请求对象,每个接口都会对应一个request对象
|
|
|
|
TextToImageRequest req = new TextToImageRequest(); |
|
|
|
req.setPrompt(param.getPrompt()); |
|
|
|
|
|
|
|
//描述词处理
|
|
|
|
//负面提示词
|
|
|
|
String negaPrompt = "lowres,bad anatomy,bad hands,text,error,missing fingers,extra digit,fewer digits,cropped,worst quality,low quality,normal quality,jpeg artifacts,signature,watermark,username,blurry,lowres,text, cropped,worst quality,low quality,normal quality,jpeg artifacts,signature, watermark,username,blurry,text,signature,watermark,simple background,toony,dated,low res,line art,flat colors,nsfw,easynegative,naked,nsfw"; |
|
|
|
//内容提示词
|
|
|
|
String contentPrompt = param.getPrompt(); |
|
|
|
//积极预设词
|
|
|
|
String activePrompt = "8k,masterpiece,best quality,ultra high res,"; |
|
|
|
String resultPrompt = activePrompt + contentPrompt; |
|
|
|
req.setPrompt(resultPrompt); |
|
|
|
//请求风格
|
|
|
|
String[] styles1 = new String[0]; |
|
|
|
switch (param.getStyleName()) { |
|
|
|
case "细腻": |
|
|
|
styles1 = new String[]{"110"}; |
|
|
|
break; |
|
|
|
case "卡通": |
|
|
|
styles1 = new String[]{"201"}; |
|
|
|
break; |
|
|
|
case "科幻": |
|
|
|
styles1 = new String[]{"114"}; |
|
|
|
break; |
|
|
|
case "中国风": |
|
|
|
styles1 = new String[]{"101"}; |
|
|
|
break; |
|
|
|
} |
|
|
|
req.setStyles(styles1); |
|
|
|
req.setStyles(new String[]{"201"}); |
|
|
|
|
|
|
|
//画布大小
|
|
|
|
ResultConfig resultConfig1 = new ResultConfig(); |
|
|
|
@ -160,7 +154,8 @@ public class StableDiffusionServiceImpl implements StableDiffusionService { |
|
|
|
paint.setPaintId(paintId); |
|
|
|
paint.setCreateTime(paintTime); |
|
|
|
paint.setImgUrl(imgStr); |
|
|
|
paint.setPrompt(param.getPrompt()); |
|
|
|
paint.setPrompt(resultPrompt); |
|
|
|
paint.setNegativePrompt(negaPrompt); |
|
|
|
paint.setModel(param.getModelName()); |
|
|
|
paint.setStyleName(param.getStyleName()); |
|
|
|
paint.setHeight(param.getHeight() == null ? "512" : String.valueOf(param.getHeight())); |
|
|
|
@ -183,16 +178,24 @@ public class StableDiffusionServiceImpl implements StableDiffusionService { |
|
|
|
}else{ |
|
|
|
//采用sd
|
|
|
|
try{ |
|
|
|
//内容提示词
|
|
|
|
String contentPrompt = param.getPrompt(); |
|
|
|
//积极预设词
|
|
|
|
String activePrompt = "8k,masterpiece,best quality,ultra high res,"; |
|
|
|
|
|
|
|
String prompt = ""; |
|
|
|
//判断prompt是否包含中文,中文则翻译,否则跳过
|
|
|
|
if(TranslateUtils.isContainChinese(param.getPrompt())){ |
|
|
|
if(TranslateUtils.isContainChinese(contentPrompt)){ |
|
|
|
//调用翻译api
|
|
|
|
prompt = translate(param.getPrompt()); |
|
|
|
prompt = translate(contentPrompt); |
|
|
|
}else{ |
|
|
|
prompt = param.getPrompt(); |
|
|
|
prompt = contentPrompt; |
|
|
|
} |
|
|
|
log.info("正向提示词为:【{}】",prompt); |
|
|
|
String resultPrompt = activePrompt + prompt; |
|
|
|
|
|
|
|
//lora风格处理
|
|
|
|
resultPrompt = resultPrompt + "," + "<" + param.getModelName() +">"; |
|
|
|
log.info("正向提示词为:【{}】",resultPrompt); |
|
|
|
String negaPromptText = ""; |
|
|
|
//判断反向prompt是否包含中文,中文则翻译,否则跳过
|
|
|
|
if(StringUtils.isNotBlank(param.getNegativePrompt())){ |
|
|
|
@ -206,20 +209,19 @@ public class StableDiffusionServiceImpl implements StableDiffusionService { |
|
|
|
negaPromptText = param.getNegativePrompt(); |
|
|
|
} |
|
|
|
|
|
|
|
log.info("反向提示词为:【{}】",negaPromptText); |
|
|
|
|
|
|
|
Map<String, Object> map = new HashMap<>(); |
|
|
|
String negaPrompt = "easynegative,nsfw,naked"; |
|
|
|
String negaPrompt = "lowres,bad anatomy,bad hands,text,error,missing fingers,extra digit,fewer digits,cropped,worst quality,low quality,normal quality,jpeg artifacts,signature,watermark,username,blurry,lowres,text, cropped,worst quality,low quality,normal quality,jpeg artifacts,signature, watermark,username,blurry,text,signature,watermark,simple background,toony,dated,low res,line art,flat colors,nsfw,easynegative,naked,nsfw"; |
|
|
|
if(StringUtils.isNotBlank(param.getNegativePrompt())){ |
|
|
|
negaPrompt = negaPrompt + "," + negaPromptText; |
|
|
|
} |
|
|
|
log.info("反向提示词为:【{}】",negaPrompt); |
|
|
|
Double eta = param.getEta() == null ? 0 : param.getEta(); |
|
|
|
Integer batchSize = param.getBatchSize() == null ? 1 :param.getBatchSize(); |
|
|
|
Integer seed = param.getSeed() == null ? -1 : param.getSeed(); |
|
|
|
Double cfgScale = param.getCfgScale() == null ? 7 : param.getCfgScale(); |
|
|
|
Integer steps = param.getSteps() == null ? 25 : param.getSteps(); |
|
|
|
String samplerIndex = StringUtils.isEmpty(param.getSamplerIndex()) ? "DPM++ 2S a Karras" : param.getSamplerIndex(); |
|
|
|
map.put("prompt", prompt); |
|
|
|
map.put("prompt", resultPrompt); |
|
|
|
map.put("restore_faces",false); //面部修复,卡通模型不支持,只适合真人模型
|
|
|
|
map.put("tiling",false); //生成可平铺的周期性图片
|
|
|
|
map.put("eta",eta); //取值为0-1
|
|
|
|
@ -255,8 +257,8 @@ public class StableDiffusionServiceImpl implements StableDiffusionService { |
|
|
|
paint.setPaintId(paintId); |
|
|
|
paint.setCreateTime(paintTime); |
|
|
|
paint.setImgUrl(imgStr); |
|
|
|
paint.setPrompt(param.getPrompt()); |
|
|
|
paint.setNegativePrompt(negaPrompt); |
|
|
|
paint.setPrompt(prompt); |
|
|
|
paint.setNegativePrompt(negaPromptText); |
|
|
|
paint.setEta(eta); |
|
|
|
paint.setBatchSize(batchSize); |
|
|
|
paint.setSeed(seed); |
|
|
|
@ -287,7 +289,215 @@ public class StableDiffusionServiceImpl implements StableDiffusionService { |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public TextToImgVo textToImgLove(TextToImgLoveDto param) { |
|
|
|
public List<String> textToImgLove(TextToImgLoveDto param) { |
|
|
|
//描述词处理
|
|
|
|
//内容提示词
|
|
|
|
String contentPrompt = param.getPrompt(); |
|
|
|
//场景提示词
|
|
|
|
String scenePrompt = param.getScenePrompt(); |
|
|
|
//内容+场景组合提示词
|
|
|
|
String resultPrompt = contentPrompt + "," + scenePrompt; |
|
|
|
//积极预设词
|
|
|
|
String activePrompt = ",8k,masterpiece,best quality,ultra high res,portrait,"; |
|
|
|
//反向提示词
|
|
|
|
String negaPrompt = "lowres,bad anatomy,bad hands,text,error,missing fingers,extra digit,fewer digits,cropped,worst quality,low quality,normal quality,jpeg artifacts,signature,watermark,username,blurry,lowres,text, cropped,worst quality,low quality,normal quality,jpeg artifacts,signature, watermark,username,blurry,text,signature,watermark,simple background,toony,dated,low res,line art,flat colors,nsfw,easynegative,nsfw,naked"; |
|
|
|
|
|
|
|
//配置控制采用sd还是tx文生图
|
|
|
|
int button = redisService.getCacheObject(RedisKeyConstant.AI_PAINT_BUTTON); |
|
|
|
if(button == AiPaintButtonEnum.TX.getCode()){ |
|
|
|
//采用tx
|
|
|
|
//男头提示词
|
|
|
|
String boyHeadStr = "1个男孩" + activePrompt + resultPrompt; |
|
|
|
//女头提示词
|
|
|
|
String girlHeadStr = "1个女孩" + activePrompt + resultPrompt; |
|
|
|
String boyHead = getCoupleHead(boyHeadStr,negaPrompt,param.getPlatform(), param.getPainterId(), param.getPainterName(), param.getStyleName(),button); |
|
|
|
log.info("腾讯男头像提示词为:【{}】",boyHead); |
|
|
|
String girlHead = getCoupleHead(girlHeadStr,negaPrompt,param.getPlatform(), param.getPainterId(), param.getPainterName(), param.getStyleName(),button); |
|
|
|
log.info("腾讯女头像提示词为:【{}】",girlHeadStr); |
|
|
|
List<String> imgList = new ArrayList<>(); |
|
|
|
imgList.add(boyHead); |
|
|
|
imgList.add(girlHead); |
|
|
|
return imgList; |
|
|
|
}else{ |
|
|
|
//采用sd
|
|
|
|
try{ |
|
|
|
//最终结果词
|
|
|
|
String prompt = ""; |
|
|
|
//判断组合提示词是否包含中文,中文则翻译,否则跳过
|
|
|
|
if(TranslateUtils.isContainChinese(resultPrompt)){ |
|
|
|
//调用翻译api
|
|
|
|
prompt = translate(resultPrompt); |
|
|
|
}else{ |
|
|
|
prompt = resultPrompt; |
|
|
|
} |
|
|
|
|
|
|
|
//男头提示词
|
|
|
|
String boyHeadStr = "(1boy)" + activePrompt + prompt; |
|
|
|
//女头提示词
|
|
|
|
String girlHeadStr = "(1girl)" + activePrompt + prompt; |
|
|
|
|
|
|
|
String boyHead = getCoupleHead(boyHeadStr,negaPrompt,param.getPlatform(), param.getPainterId(), param.getPainterName(), param.getStyleName(),button); |
|
|
|
log.info("sd男头像提示词为:【{}】",boyHeadStr); |
|
|
|
String girlHead = getCoupleHead(girlHeadStr,negaPrompt,param.getPlatform(), param.getPainterId(), param.getPainterName(), param.getStyleName(),button); |
|
|
|
log.info("sd女头像提示词为:【{}】",girlHeadStr); |
|
|
|
List<String> imgList = new ArrayList<>(); |
|
|
|
imgList.add(boyHead); |
|
|
|
imgList.add(girlHead); |
|
|
|
return imgList; |
|
|
|
}catch (Exception e){ |
|
|
|
log.error("文本翻译错误!"+e); |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 情侣头像专用绘制方法 |
|
|
|
* @param button sd/tx |
|
|
|
* @param headStr 头像描述词 |
|
|
|
* @param negaPrompt 反向描述词 |
|
|
|
* @param platform 平台 |
|
|
|
* @param painterId 绘图者id |
|
|
|
* @param painterName 绘图者名称 |
|
|
|
* @param styleName 风格名称 |
|
|
|
* @return - |
|
|
|
*/ |
|
|
|
private String getCoupleHead(String headStr,String negaPrompt,String platform,Long painterId,String painterName,String styleName,int button){ |
|
|
|
|
|
|
|
if(button == AiPaintButtonEnum.TX.getCode()){ |
|
|
|
//采用腾讯文生图
|
|
|
|
try{ |
|
|
|
Credential cred = new Credential(tencentTranslateConfig.getSecretId(), tencentTranslateConfig.getSecretKey()); |
|
|
|
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
|
|
|
HttpProfile httpProfile = new HttpProfile(); |
|
|
|
httpProfile.setEndpoint("aiart.tencentcloudapi.com"); |
|
|
|
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
|
|
|
ClientProfile clientProfile = new ClientProfile(); |
|
|
|
clientProfile.setHttpProfile(httpProfile); |
|
|
|
// 实例化要请求产品的client对象,clientProfile是可选的
|
|
|
|
AiartClient client = new AiartClient(cred, "ap-guangzhou", clientProfile); |
|
|
|
// 实例化一个请求对象,每个接口都会对应一个request对象
|
|
|
|
TextToImageRequest req = new TextToImageRequest(); |
|
|
|
|
|
|
|
//请求风格
|
|
|
|
req.setStyles(new String[]{"201"}); |
|
|
|
|
|
|
|
//画布大小(头像尺寸固定)
|
|
|
|
ResultConfig resultConfig1 = new ResultConfig(); |
|
|
|
resultConfig1.setResolution("768:768"); |
|
|
|
req.setResultConfig(resultConfig1); |
|
|
|
|
|
|
|
//头像描述词
|
|
|
|
req.setPrompt(headStr); |
|
|
|
//反向提示词
|
|
|
|
req.setNegativePrompt(negaPrompt); |
|
|
|
// 返回的resp是一个TextToImageResponse的实例,与请求对象对应
|
|
|
|
TextToImageResponse resp = client.TextToImage(req); |
|
|
|
String images = resp.getResultImage(); |
|
|
|
List<String> list = new ArrayList<>(); |
|
|
|
list.add(images); |
|
|
|
String paintId = null; |
|
|
|
Date paintTime = null; |
|
|
|
for (String image : list) { |
|
|
|
//base64转file
|
|
|
|
MultipartFile file = new Base64ToMultipartFileUtils(image, "data:image/png;base64", "file", "tempSDImg"); |
|
|
|
//上传图片到七牛云/minio
|
|
|
|
//String imgStr = remoteFileService.uploadBanner(file).getData();
|
|
|
|
//上传图片到七牛云并存入sd文件夹
|
|
|
|
String imgStr = remoteFileService.uploadQiNiu(file,8).getData(); |
|
|
|
//保存生辰该图片到ai绘画表
|
|
|
|
AiPaint paint = new AiPaint(); |
|
|
|
paintId = IdUtil.getSnowflakeNextIdStr(); |
|
|
|
paintTime = new Date(); |
|
|
|
paint.setPaintId(paintId); |
|
|
|
paint.setCreateTime(paintTime); |
|
|
|
paint.setImgUrl(imgStr); |
|
|
|
paint.setPrompt(headStr); |
|
|
|
paint.setNegativePrompt(negaPrompt); |
|
|
|
paint.setModel("腾讯情侣头像"); |
|
|
|
paint.setStyleName(styleName); |
|
|
|
paint.setHeight("768"); |
|
|
|
paint.setWidth("768"); |
|
|
|
paint.setIsShow("1"); |
|
|
|
paint.setSource(platform); |
|
|
|
paint.setPainterId(painterId); |
|
|
|
paint.setPainterName(painterName); |
|
|
|
aiPaintService.insert(paint); |
|
|
|
return image; |
|
|
|
} |
|
|
|
} catch (TencentCloudSDKException e) { |
|
|
|
log.error("腾讯文生图情侣头像调用错误!"+e.getMessage()); |
|
|
|
throw new ServiceException(e.getMessage(),500); |
|
|
|
} |
|
|
|
}else{ |
|
|
|
Map<String, Object> map = new HashMap<>(); |
|
|
|
Double eta = 0.0; |
|
|
|
Integer batchSize = 1; |
|
|
|
Integer seed = -1; |
|
|
|
Double cfgScale = 7.0; |
|
|
|
Integer steps = 25; |
|
|
|
String samplerIndex = "DPM++ SDE Karras"; |
|
|
|
|
|
|
|
map.put("prompt", headStr); |
|
|
|
map.put("restore_faces",false); //面部修复,卡通模型不支持,只适合真人模型
|
|
|
|
map.put("tiling",false); //生成可平铺的周期性图片
|
|
|
|
map.put("eta",eta); //取值为0-1
|
|
|
|
map.put("batch_size",batchSize); //生成图片数可调
|
|
|
|
map.put("seed",seed); //种子
|
|
|
|
map.put("cfg_scale",cfgScale); //精细度可调
|
|
|
|
map.put("steps",steps); //采样步数可调
|
|
|
|
map.put("sampler_index",samplerIndex); //采样风格可调
|
|
|
|
map.put("negative_prompt",negaPrompt); |
|
|
|
map.put("width",512); |
|
|
|
map.put("height",512); |
|
|
|
log.info("请求stable_diffusion情侣头像请求体为:【{}】", JSON.toJSONString(map)); |
|
|
|
try{ |
|
|
|
JSONObject jsonObject = restTemplate.postForObject(stableDiffusionConfig.getTxt2ImgUrl(), map, JSONObject.class); |
|
|
|
//log.info("请求stable_diffusion响应体的为:【{}】", JSON.toJSONString(jsonObject));
|
|
|
|
if(jsonObject != null && jsonObject.getJSONArray("images").size() > 0){ |
|
|
|
List<String> images = jsonObject.getJSONArray("images").toJavaList(String.class); |
|
|
|
String paintId = null; |
|
|
|
Date paintTime = null; |
|
|
|
for (String image : images) { |
|
|
|
//base64转file
|
|
|
|
MultipartFile file = new Base64ToMultipartFileUtils(image, "data:image/png;base64", "file", "tempSDImg"); |
|
|
|
//上传图片到七牛云/minio
|
|
|
|
//String imgStr = remoteFileService.uploadBanner(file).getData();
|
|
|
|
//上传图片到七牛云并存入情侣头像文件夹
|
|
|
|
String imgStr = remoteFileService.uploadQiNiu(file,8).getData(); |
|
|
|
//保存生辰该图片到ai绘画表
|
|
|
|
AiPaint paint = new AiPaint(); |
|
|
|
paintId = IdUtil.getSnowflakeNextIdStr(); |
|
|
|
paintTime = new Date(); |
|
|
|
paint.setPaintId(paintId); |
|
|
|
paint.setCreateTime(paintTime); |
|
|
|
paint.setImgUrl(imgStr); |
|
|
|
paint.setPrompt(headStr); |
|
|
|
paint.setNegativePrompt(negaPrompt); |
|
|
|
paint.setEta(eta); |
|
|
|
paint.setBatchSize(batchSize); |
|
|
|
paint.setSeed(seed); |
|
|
|
paint.setCfgScale(cfgScale); |
|
|
|
paint.setSteps(steps); |
|
|
|
paint.setSamplerIndex(samplerIndex); |
|
|
|
paint.setModel("sd情侣头像"); |
|
|
|
paint.setStyleName(styleName); |
|
|
|
paint.setHeight("512"); |
|
|
|
paint.setWidth("512"); |
|
|
|
paint.setIsShow("1"); |
|
|
|
paint.setSource(platform); |
|
|
|
paint.setPainterId(painterId); |
|
|
|
paint.setPainterName(painterName); |
|
|
|
aiPaintService.insert(paint); |
|
|
|
return image; |
|
|
|
} |
|
|
|
} |
|
|
|
}catch (Exception e){ |
|
|
|
log.error("情侣头像sd调用失败!,原因为:【{}】",e.getMessage()); |
|
|
|
throw new ServiceException("情侣头像绘制失败!",500); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
|