feat: dmxapi generate multiple image (#6632)

* chore(version): 1.3.8

* 新增自动添加

* 图片自增功能优化

---------

Co-authored-by: kangfenmao <kangfenmao@qq.com>
This commit is contained in:
Caelan 2025-05-30 10:35:21 +08:00 committed by GitHub
parent 911baf2c99
commit 61a658611d
8 changed files with 73 additions and 17 deletions

View File

@ -940,7 +940,11 @@
"seed_tip": "Controls upscaling randomness",
"magic_prompt_option_tip": "Intelligently enhances upscaling prompts"
},
"text_desc_required": "Please enter image description first"
"text_desc_required": "Please enter image description first",
"req_error_text": "Operation failed. Please try again. Avoid using 'copyrighted' or 'sensitive' words in your prompt.",
"auto_create_paint": "Auto-create image",
"auto_create_paint_tip": "After the image is generated, a new image will be created automatically."
},
"prompts": {
"explanation": "Explain this concept to me",

View File

@ -940,7 +940,10 @@
},
"rendering_speed": "レンダリング速度",
"translating": "翻訳中...",
"text_desc_required": "画像の説明を先に入力してください"
"text_desc_required": "画像の説明を先に入力してください",
"req_error_text": "実行に失敗しました。もう一度お試しください。プロンプトに「著作権用語」や「センシティブな用語」を含めないでください。",
"auto_create_paint": "画像を自動作成",
"auto_create_paint_tip": "画像が生成された後、自動的に新しい画像が作成されます。"
},
"prompts": {
"explanation": "この概念を説明してください",

View File

@ -940,7 +940,10 @@
"seed_tip": "Контролирует случайный характер увеличения изображений для воспроизводимых результатов",
"magic_prompt_option_tip": "Улучшает увеличение изображений с помощью интеллектуального оптимизирования промптов"
},
"text_desc_required": "Пожалуйста, сначала введите описание изображения"
"text_desc_required": "Пожалуйста, сначала введите описание изображения",
"req_error_text": "Операция не удалась, повторите попытку. Пожалуйста, избегайте защищенных авторским правом терминов и конфиденциальных слов в запросах.",
"auto_create_paint": "Автоматическое создание изображения",
"auto_create_paint_tip": "После генерации изображения будет автоматически создано новое."
},
"prompts": {
"explanation": "Объясните мне этот концепт",

View File

@ -940,7 +940,10 @@
"seed_tip": "控制放大结果的随机性",
"magic_prompt_option_tip": "智能优化放大提示词"
},
"text_desc_required": "请先输入图片描述"
"text_desc_required": "请先输入图片描述",
"req_error_text" : "运行失败,请重试。提示词避免“版权词”和”敏感词”哦。",
"auto_create_paint": "自动新建图片",
"auto_create_paint_tip": "在图片生成后,会自动新建图片"
},
"prompts": {
"explanation": "帮我解释一下这个概念",

View File

@ -940,7 +940,10 @@
"magic_prompt_option_tip": "智能優化放大提示詞"
},
"rendering_speed": "渲染速度",
"text_desc_required": "請先輸入圖片描述"
"text_desc_required": "請先輸入圖片描述",
"req_error_text" : "运行失败,请重试。提示词避免“版权词”和”敏感词”哦。",
"auto_create_paint": "自動新增圖片",
"auto_create_paint_tip": "圖片生成後,會自動新增圖片"
},
"prompts": {
"explanation": "幫我解釋一下這個概念",

View File

@ -2,6 +2,7 @@ import { PlusOutlined, RedoOutlined } from '@ant-design/icons'
import DMXAPIToImg from '@renderer/assets/images/providers/DMXAPI-to-img.webp'
import { Navbar, NavbarCenter, NavbarRight } from '@renderer/components/app/Navbar'
import { VStack } from '@renderer/components/Layout'
import { HStack } from '@renderer/components/Layout'
import Scrollbar from '@renderer/components/Scrollbar'
import { isMac } from '@renderer/config/constant'
import { getProviderLogo } from '@renderer/config/providers'
@ -13,9 +14,9 @@ import FileManager from '@renderer/services/FileManager'
import { useAppDispatch } from '@renderer/store'
import { setGenerating } from '@renderer/store/runtime'
import type { FileType, PaintingsState } from '@renderer/types'
import { getErrorMessage, uuid } from '@renderer/utils'
import { uuid } from '@renderer/utils'
import { DmxapiPainting, PaintingAction } from '@types'
import { Avatar, Button, Input, Radio, Select, Tooltip } from 'antd'
import { Avatar, Button, Input, Radio, Select, Switch, Tooltip } from 'antd'
import TextArea from 'antd/es/input/TextArea'
import { Info } from 'lucide-react'
import React, { FC } from 'react'
@ -71,6 +72,16 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
}
}
const getNewPaintingPanel = (updates: Partial<DmxapiPainting>) => {
const copyPainting = {
...painting,
...updates,
id: uuid()
}
setPainting(addPainting('DMXAPIPaintings', copyPainting))
}
const modelOptions = TEXT_TO_IMAGES_MODELS.map((model) => ({
label: model.name,
value: model.id
@ -108,6 +119,10 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
}
}
const onChangeAutoCreate = (v: boolean) => {
updatePaintingState({ autoCreate: v })
}
const onInputSeed = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
// 允许空值或合法整数,且大于等于 -1
@ -194,8 +209,7 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
})
if (!response.ok) {
const errorData = await response.json()
throw new Error(errorData.error?.message || '操作失败')
throw new Error('操作失败,请稍后重试')
}
const data = await response.json()
@ -251,7 +265,7 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
checkProviderStatus()
// 处理已有文件
if (painting.files.length > 0) {
if (painting.files.length > 0 && !painting.autoCreate) {
const confirmed = await window.modal.confirm({
content: t('paintings.regenerate.confirm'),
centered: true
@ -277,11 +291,25 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
const downloadedFiles = await downloadImages(urls)
const validFiles = downloadedFiles.filter((file): file is FileType => file !== null)
// 删除之前的图片
await FileManager.deleteFiles(painting.files)
// 保存文件并更新状态
await FileManager.addFiles(validFiles)
updatePaintingState({ files: validFiles, urls })
if (validFiles?.length > 0) {
if (painting.autoCreate && painting.files.length > 0) {
// 保存文件并更新状态
await FileManager.addFiles(validFiles)
getNewPaintingPanel({ files: validFiles, urls })
} else {
// 删除之前的图片
await FileManager.deleteFiles(painting.files)
// 保存文件并更新状态
await FileManager.addFiles(validFiles)
updatePaintingState({ files: validFiles, urls })
}
} else {
window.message.warning({
content: t('paintings.req_error_text'),
key: 'empty-url-warning'
})
}
}
} catch (error) {
// 错误处理
@ -290,7 +318,7 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
content:
error.message.startsWith('paintings.') || error.message.startsWith('error.')
? t(error.message)
: getErrorMessage(error),
: t('paintings.req_error_text'),
centered: true
})
}
@ -442,6 +470,16 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
))}
</RadioTextBox>
</SliderContainer>
<SettingTitle style={{ marginBottom: 5, marginTop: 15 }}>
{t('paintings.auto_create_paint')}
<Tooltip title={t('paintings.auto_create_paint_tip')}>
<InfoIcon />
</Tooltip>
</SettingTitle>
<HStack>
<Switch checked={painting.autoCreate} onChange={(checked) => onChangeAutoCreate(checked)} />
</HStack>
</LeftContainer>
<MainContainer>
<Artboard

View File

@ -90,5 +90,6 @@ export const DEFAULT_PAINTING: DmxapiPainting = {
n: 1,
seed: '',
style_type: '',
model: TEXT_TO_IMAGES_MODELS[0].id
model: TEXT_TO_IMAGES_MODELS[0].id,
autoCreate: false
}

View File

@ -266,6 +266,7 @@ export interface DmxapiPainting extends PaintingParams {
image_size?: string
seed?: string
style_type?: string
autoCreate?: boolean
}
export type PaintingAction = Partial<GeneratePainting & RemixPainting & EditPainting & ScalePainting> & PaintingParams