diff --git a/portal-ui/src/views/ChangeFace.vue b/portal-ui/src/views/ChangeFace.vue
index 8e14080..e6a7576 100644
--- a/portal-ui/src/views/ChangeFace.vue
+++ b/portal-ui/src/views/ChangeFace.vue
@@ -218,7 +218,7 @@ export default {
method: 'POST',
data: {
text: this.text || this.textPlaceholder,
- firstUrl: [this.firstUrl.url, this.secondUrl.url],
+ imageUrls: [this.firstUrl.url, this.secondUrl.url],
functionType: '13',
tags: tags.join(',')
}
diff --git a/portal-ui/src/views/Image.vue b/portal-ui/src/views/Image.vue
index d4a3cd7..c10fc7a 100644
--- a/portal-ui/src/views/Image.vue
+++ b/portal-ui/src/views/Image.vue
@@ -22,6 +22,8 @@
@@ -73,23 +75,22 @@
{{ $t('common.aspectRatioLabel') }}
- auto
- 1:1
- 1:4
- 1:8
- 2:3
- 3:2
- 3:4
- 4:1
- 4:3
- 4:5
- 5:4
- 8:1
- 9:16
- 16:9
- 21:9
+ auto
+ 1:1
+ 1:4
+ 1:8
+ 2:3
+ 3:2
+ 3:4
+ 4:1
+ 4:3
+ 4:5
+ 5:4
+ 8:1
+ 9:16
+ 16:9
+ 21:9
@@ -99,21 +100,21 @@
- 1K
- 2K
- 4K
+ 1K
+ 2K
+ 4K
-
+
输出格式
- png
- jpg
+ png
+ jpg
@@ -208,7 +209,7 @@ export default {
data() {
return {
prefixCls: 'image',
- firstUrl: '',
+ firstUrl: [],
text: '',
current: 1,
generateLoading: false,
@@ -318,11 +319,27 @@ export default {
if (this.uploadType === 'upload') {
this.selectedTemplatePreview = ''
this.selectedTemplate = null
- this.firstUrl = ''
+ this.firstUrl = []
} else {
- this.firstUrl = ''
+ this.firstUrl = []
}
},
+ getImageUrls() {
+ if (this.$datas.isEmpty(this.firstUrl)) return []
+ if (Array.isArray(this.firstUrl)) {
+ return this.firstUrl
+ .map((item) => item?.serverUrl || item?.url || '')
+ .filter((url) => !!url)
+ }
+ if (typeof this.firstUrl === 'object') {
+ const url = this.firstUrl.serverUrl || this.firstUrl.url
+ return url ? [url] : []
+ }
+ if (typeof this.firstUrl === 'string') {
+ return this.firstUrl ? [this.firstUrl] : []
+ }
+ return []
+ },
// 打开模版选择弹窗
openTemplateDialog() {
this.templateDialogVisible = true
@@ -430,10 +447,7 @@ export default {
}
},
generateImage() {
- if (!this.firstUrl || !this.firstUrl.url) {
- this.$message.error(this.$t('common.uploadImageError'))
- return
- }
+ const imageUrls = this.getImageUrls()
// image-to-image2 (current=2) 需要检查分辨率
if (this.current === 2 && !this.resolution) {
this.$message.warning(this.$t('common.proResolutionRequired'))
@@ -463,16 +477,19 @@ export default {
})
this.generateLoading = true
this.taskIdHint = ''
- nanoBananaImgToImg({
+ const requestData = {
functionType: this.current == 1 ? '11' : '12',
- imageUrl: this.firstUrl.url,
+ imageUrls,
text: this.text,
tags: tags.join(','),
aspectRatio: this.aspectRatio,
resolution: this.resolution,
- outputFormat: this.outputFormat,
numImages: 1
- })
+ }
+ if (this.current !== 2) {
+ requestData.outputFormat = this.outputFormat
+ }
+ nanoBananaImgToImg(requestData)
.then((res) => {
this.generateLoading = false
if (res.code == 200) {
@@ -887,22 +904,3 @@ export default {
}
}
-
-
diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/ByteApiController.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/ByteApiController.java
index e179a16..bfd3026 100644
--- a/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/ByteApiController.java
+++ b/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/ByteApiController.java
@@ -164,9 +164,6 @@ public class ByteApiController extends BaseController {
} else if (StringUtils.isNotEmpty(request.getImageUrl())) {
imageUrls.add(request.getImageUrl().trim());
}
- if (imageUrls.isEmpty()) {
- return AjaxResult.error("请提供 imageUrl 或 imageUrls");
- }
AiManager aiManager = managerService.selectAiManagerByType(functionType);
if (aiManager == null) {
@@ -196,7 +193,7 @@ public class ByteApiController extends BaseController {
return AjaxResult.error(-1, "You have a low balance, please recharge");
}
aiOrder.setText(text);
- aiOrder.setImg1(imageUrls.get(0));
+ aiOrder.setImg1(imageUrls.isEmpty() ? null : imageUrls.get(0));
NanoBananaRequest nanoRequest = NanoBananaRequest.forImageToImage(
text,
@@ -347,9 +344,13 @@ public class ByteApiController extends BaseController {
return AjaxResult.error("text is null");
}
- Object firstUrl = request.getFirstUrl();
- if (null == firstUrl) {
- return AjaxResult.error("firstUrl is null");
+ List imageUrls = new ArrayList<>();
+ if (request.getImageUrls() != null && !request.getImageUrls().isEmpty()) {
+ for (String u : request.getImageUrls()) {
+ if (StringUtils.isNotEmpty(u)) {
+ imageUrls.add(u.trim());
+ }
+ }
}
String resolution = StringUtils.isNotBlank(request.getResolution())
@@ -363,13 +364,7 @@ public class ByteApiController extends BaseController {
}
aiOrder.setText(text);
- aiOrder.setImg1(firstUrl.toString());
-
- // 4. 组装NanoBanana接口参数 - 图生图
- List imageUrls = new ArrayList<>();
- if (firstUrl != null) {
- imageUrls.add(firstUrl.toString());
- }
+ aiOrder.setImg1(imageUrls.isEmpty() ? null : imageUrls.get(0));
NanoBananaRequest nanoRequest = NanoBananaRequest.forImageToImage(
text,
diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/request/ByteApiRequest.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/request/ByteApiRequest.java
index e7d2a99..3c4a651 100644
--- a/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/request/ByteApiRequest.java
+++ b/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/request/ByteApiRequest.java
@@ -37,6 +37,9 @@ public class ByteApiRequest {
@ApiModelProperty(name = "分辨率 1K/2K/4K")
private String resolution;
+ @ApiModelProperty(name = "图生图参考图列表,可为空")
+ private List imageUrls;
+
/**
* NanoBanana 接口版本:v1(/generate)、v2(/generate-2)、pro(/generate-pro),默认 v2 兼容旧逻辑
*/
diff --git a/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/request/NanoBananaPortalImgRequest.java b/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/request/NanoBananaPortalImgRequest.java
index 0db1cc0..f7b8ca2 100644
--- a/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/request/NanoBananaPortalImgRequest.java
+++ b/web-api/ruoyi-admin/src/main/java/com/ruoyi/api/request/NanoBananaPortalImgRequest.java
@@ -35,10 +35,10 @@ public class NanoBananaPortalImgRequest {
@ApiModelProperty("标签字符串")
private String tags;
- @ApiModelProperty("单张参考图 URL(与 imageUrls 二选一)")
+ @ApiModelProperty("单张参考图 URL(兼容字段,可为空)")
private String imageUrl;
- @ApiModelProperty("多张参考图 URL(优先于 imageUrl)")
+ @ApiModelProperty("多张参考图 URL(优先于 imageUrl,可为空数组)")
private List imageUrls;
@ApiModelProperty("输出格式:png / jpg")