mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-25 19:30:17 +08:00
feature/dmxapi_painting_custom_size (#8689)
* 修改生成图片尺寸 * fix:known problem * fix:Switching but no recovery occurred * fix:The problem of loading images * fix:text i18n
This commit is contained in:
parent
63ae211af1
commit
2ced1b2d71
@ -1507,6 +1507,7 @@
|
||||
"image": "New Image"
|
||||
}
|
||||
},
|
||||
"custom_size": "Custom Size",
|
||||
"edit": {
|
||||
"image_file": "Edited Image",
|
||||
"magic_prompt_option_tip": "Intelligently enhances editing prompts",
|
||||
@ -1629,6 +1630,7 @@
|
||||
},
|
||||
"text_desc_required": "Please enter image description first",
|
||||
"title": "Images",
|
||||
"top_up": "Top up ",
|
||||
"translating": "Translating...",
|
||||
"uploaded_input": "Uploaded input",
|
||||
"upscale": {
|
||||
|
||||
@ -1507,6 +1507,7 @@
|
||||
"image": "新しい画像"
|
||||
}
|
||||
},
|
||||
"custom_size": "カスタムサイズ",
|
||||
"edit": {
|
||||
"image_file": "編集画像",
|
||||
"magic_prompt_option_tip": "編集効果を向上させるための提示詞を最適化します",
|
||||
@ -1629,6 +1630,7 @@
|
||||
},
|
||||
"text_desc_required": "画像の説明を先に入力してください",
|
||||
"title": "画像",
|
||||
"top_up": "チャージする",
|
||||
"translating": "翻訳中...",
|
||||
"uploaded_input": "アップロード済みの入力",
|
||||
"upscale": {
|
||||
|
||||
@ -1507,6 +1507,7 @@
|
||||
"image": "Новое изображение"
|
||||
}
|
||||
},
|
||||
"custom_size": "Пользовательский размер",
|
||||
"edit": {
|
||||
"image_file": "Изображение для редактирования",
|
||||
"magic_prompt_option_tip": "Интеллектуально оптимизирует подсказки для улучшения эффекта редактирования",
|
||||
@ -1629,6 +1630,7 @@
|
||||
},
|
||||
"text_desc_required": "Пожалуйста, сначала введите описание изображения",
|
||||
"title": "Изображения",
|
||||
"top_up": "пополнить счёт",
|
||||
"translating": "Перевод...",
|
||||
"uploaded_input": "Загруженный ввод",
|
||||
"upscale": {
|
||||
|
||||
@ -1507,6 +1507,7 @@
|
||||
"image": "新建图片"
|
||||
}
|
||||
},
|
||||
"custom_size": "自定义尺寸",
|
||||
"edit": {
|
||||
"image_file": "编辑的图像",
|
||||
"magic_prompt_option_tip": "智能优化编辑提示词",
|
||||
@ -1629,6 +1630,7 @@
|
||||
},
|
||||
"text_desc_required": "请先输入图片描述",
|
||||
"title": "图片",
|
||||
"top_up": "充值",
|
||||
"translating": "翻译中...",
|
||||
"uploaded_input": "已上传输入",
|
||||
"upscale": {
|
||||
|
||||
@ -1507,6 +1507,7 @@
|
||||
"image": "新繪圖"
|
||||
}
|
||||
},
|
||||
"custom_size": "自訂尺寸",
|
||||
"edit": {
|
||||
"image_file": "編輯圖像",
|
||||
"magic_prompt_option_tip": "智能優化編輯提示詞",
|
||||
@ -1629,6 +1630,7 @@
|
||||
},
|
||||
"text_desc_required": "請先輸入圖片描述",
|
||||
"title": "繪圖",
|
||||
"top_up": "儲值",
|
||||
"translating": "翻譯中...",
|
||||
"uploaded_input": "已上傳輸入",
|
||||
"upscale": {
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
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 { HStack, 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'
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { usePaintings } from '@renderer/hooks/usePaintings'
|
||||
import { useAllProviders } from '@renderer/hooks/useProvider'
|
||||
import { useRuntime } from '@renderer/hooks/useRuntime'
|
||||
@ -16,7 +15,7 @@ import { setGenerating } from '@renderer/store/runtime'
|
||||
import type { FileMetadata, PaintingsState } from '@renderer/types'
|
||||
import { uuid } from '@renderer/utils'
|
||||
import { DmxapiPainting } from '@types'
|
||||
import { Avatar, Button, Input, Radio, Segmented, Select, Switch, Tooltip } from 'antd'
|
||||
import { Avatar, Button, Input, InputNumber, Segmented, Select, Switch, Tooltip } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import { Info } from 'lucide-react'
|
||||
import React, { FC, useEffect, useRef, useState } from 'react'
|
||||
@ -34,9 +33,9 @@ import {
|
||||
COURSE_URL,
|
||||
DEFAULT_PAINTING,
|
||||
GetModelGroup,
|
||||
IMAGE_SIZES,
|
||||
MODEOPTIONS,
|
||||
STYLE_TYPE_OPTIONS
|
||||
STYLE_TYPE_OPTIONS,
|
||||
TOP_UP_URL
|
||||
} from './config/DmxapiConfig'
|
||||
|
||||
const generateRandomSeed = () => Math.floor(Math.random() * 1000000).toString()
|
||||
@ -45,7 +44,6 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
const [mode] = useState<keyof PaintingsState>('DMXAPIPaintings')
|
||||
const { DMXAPIPaintings, addPainting, removePainting, updatePainting } = usePaintings()
|
||||
const [painting, setPainting] = useState<DmxapiPainting>(DMXAPIPaintings?.[0] || DEFAULT_PAINTING)
|
||||
const { theme } = useTheme()
|
||||
const { t } = useTranslation()
|
||||
const providers = useAllProviders()
|
||||
const providerOptions = Options.map((option) => {
|
||||
@ -88,6 +86,11 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
paths: []
|
||||
})
|
||||
|
||||
// 自定义尺寸相关状态
|
||||
const [isCustomSize, setIsCustomSize] = useState(false)
|
||||
const [customWidth, setCustomWidth] = useState<number | undefined>()
|
||||
const [customHeight, setCustomHeight] = useState<number | undefined>()
|
||||
|
||||
const modeOptions = MODEOPTIONS.map((ele) => {
|
||||
return {
|
||||
label: t(ele.label),
|
||||
@ -144,25 +147,45 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
updatePainting('DMXAPIPaintings', updatedPainting)
|
||||
}
|
||||
|
||||
const getNewPainting = (params?: Partial<DmxapiPainting>) => {
|
||||
clearImages()
|
||||
const generationMode = params?.generationMode || painting?.generationMode || MODEOPTIONS[0].value
|
||||
const modelGroups = getModelOptions(generationMode as generationModeType)
|
||||
// 获取第一个非空分组的第一个模型
|
||||
let firstModel = ''
|
||||
const getFirstModelInfo = (v: generationModeType) => {
|
||||
const modelGroups = getModelOptions(v)
|
||||
|
||||
let model = ''
|
||||
let priceModel = ''
|
||||
let image_size = ''
|
||||
for (const provider of Object.keys(modelGroups)) {
|
||||
if (modelGroups[provider].length > 0) {
|
||||
firstModel = modelGroups[provider][0].id
|
||||
if (modelGroups[provider] && modelGroups[provider].length > 0) {
|
||||
model = modelGroups[provider][0].id
|
||||
priceModel = modelGroups[provider][0].price
|
||||
image_size = modelGroups[provider][0].image_sizes[0].value
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
model,
|
||||
priceModel,
|
||||
image_size,
|
||||
modelGroups
|
||||
}
|
||||
}
|
||||
|
||||
const getNewPainting = (params?: Partial<DmxapiPainting>) => {
|
||||
clearImages()
|
||||
|
||||
const generationMode = params?.generationMode || painting?.generationMode || MODEOPTIONS[0].value
|
||||
|
||||
const { model, priceModel, image_size, modelGroups } = getFirstModelInfo(generationMode)
|
||||
|
||||
return {
|
||||
...DEFAULT_PAINTING,
|
||||
id: uuid(),
|
||||
seed: generateRandomSeed(),
|
||||
generationMode,
|
||||
model: firstModel,
|
||||
model,
|
||||
modelGroups,
|
||||
priceModel,
|
||||
image_size,
|
||||
...params
|
||||
}
|
||||
}
|
||||
@ -180,7 +203,7 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
const onSelectModel = (modelId: string) => {
|
||||
const model = allModels.find((m) => m.id === modelId)
|
||||
if (model) {
|
||||
updatePaintingState({ model: modelId, priceModel: model.price })
|
||||
updatePaintingState({ model: modelId, priceModel: model.price, image_size: model.image_sizes[0].value })
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,8 +212,34 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
}
|
||||
|
||||
const onSelectImageSize = (v: string) => {
|
||||
const size = IMAGE_SIZES.find((i) => i.value === v)
|
||||
size && updatePaintingState({ image_size: size.value, aspect_ratio: size.label })
|
||||
if (v === 'custom') {
|
||||
setIsCustomSize(true)
|
||||
// 如果有自定义尺寸值,使用它们
|
||||
if (customWidth && customHeight) {
|
||||
updatePaintingState({ image_size: `${customWidth}x${customHeight}`, aspect_ratio: 'custom' })
|
||||
}
|
||||
} else {
|
||||
setIsCustomSize(false)
|
||||
const currentModel = allModels.find((m) => m.id === painting.model)
|
||||
const size = currentModel?.image_sizes?.find((i) => i.value === v)
|
||||
size && updatePaintingState({ image_size: size.value, aspect_ratio: size.label })
|
||||
}
|
||||
}
|
||||
|
||||
const onCustomSizeChange = (value: number | null, type: string) => {
|
||||
if (value === null) return
|
||||
|
||||
if (type === 'width') {
|
||||
setCustomWidth(value)
|
||||
if (customHeight) {
|
||||
updatePaintingState({ image_size: `${value}x${customHeight}`, aspect_ratio: 'custom' })
|
||||
}
|
||||
} else if (type === 'height') {
|
||||
setCustomHeight(value)
|
||||
if (customWidth) {
|
||||
updatePaintingState({ image_size: `${customWidth}x${value}`, aspect_ratio: 'custom' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const onSelectStyleType = (v: string) => {
|
||||
@ -251,27 +300,21 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
}
|
||||
|
||||
const onGenerationModeChange = (v: generationModeType) => {
|
||||
clearImages()
|
||||
const newModelGroups = getModelOptions(v)
|
||||
setModelOptions(newModelGroups)
|
||||
|
||||
// 获取第一个非空分组的第一个模型
|
||||
let firstModel = ''
|
||||
let priceModel = ''
|
||||
for (const provider of Object.keys(newModelGroups)) {
|
||||
if (newModelGroups[provider] && newModelGroups[provider].length > 0) {
|
||||
firstModel = newModelGroups[provider][0].id
|
||||
priceModel = newModelGroups[provider][0].price
|
||||
break
|
||||
}
|
||||
if (isLoading) {
|
||||
return
|
||||
}
|
||||
|
||||
clearImages()
|
||||
|
||||
const { model, priceModel, image_size, modelGroups } = getFirstModelInfo(v)
|
||||
|
||||
setModelOptions(modelGroups)
|
||||
|
||||
// 如果有urls,创建新的painting
|
||||
if (Array.isArray(painting.urls) && painting.urls.length > 0) {
|
||||
const newPainting = getNewPainting({
|
||||
generationMode: v,
|
||||
model: firstModel, // 使用新模式下的第一个模型
|
||||
priceModel: priceModel
|
||||
model
|
||||
})
|
||||
const addedPainting = addPainting('DMXAPIPaintings', newPainting)
|
||||
setPainting(addedPainting)
|
||||
@ -279,12 +322,20 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
// 否则更新当前painting
|
||||
updatePaintingState({
|
||||
generationMode: v,
|
||||
model: firstModel, // 使用新模式下的第一个模型
|
||||
model: model,
|
||||
image_size: image_size,
|
||||
priceModel: priceModel
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const createNewPainting = () => {
|
||||
if (isLoading) {
|
||||
return
|
||||
}
|
||||
setPainting(addPainting('DMXAPIPaintings', getNewPainting()))
|
||||
}
|
||||
|
||||
// 检查提供者状态函数
|
||||
const checkProviderStatus = () => {
|
||||
if (!dmxapiProvider.enabled) {
|
||||
@ -324,10 +375,6 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
if (painting.aspect_ratio) {
|
||||
params['aspect_ratio'] = painting.aspect_ratio
|
||||
}
|
||||
|
||||
if (painting.image_size) {
|
||||
params['size'] = painting.image_size
|
||||
}
|
||||
@ -360,7 +407,7 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
}
|
||||
|
||||
if (painting.image_size) {
|
||||
params['size'] = '1024x1024'
|
||||
params['size'] = painting.image_size
|
||||
}
|
||||
|
||||
if (painting.style_type) {
|
||||
@ -562,6 +609,10 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
|
||||
const onDeletePainting = async (paintingToDelete: DmxapiPainting) => {
|
||||
if (paintingToDelete.id === painting.id) {
|
||||
if (isLoading) {
|
||||
return
|
||||
}
|
||||
|
||||
const currentIndex = DMXAPIPaintings.findIndex((p) => p.id === paintingToDelete.id)
|
||||
|
||||
if (currentIndex > 0) {
|
||||
@ -715,17 +766,21 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isLoadingModels, dynamicModelGroups]) // 依赖模型加载状态
|
||||
|
||||
// 当模型切换时,检查是否支持自定义尺寸
|
||||
useEffect(() => {
|
||||
const currentModel = allModels.find((m) => m.id === painting.model)
|
||||
if (currentModel && !currentModel.is_custom_size && isCustomSize) {
|
||||
setIsCustomSize(false)
|
||||
}
|
||||
}, [painting.model, allModels, isCustomSize])
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Navbar>
|
||||
<NavbarCenter style={{ borderRight: 'none' }}>{t('paintings.title')}</NavbarCenter>
|
||||
{isMac && (
|
||||
<NavbarRight style={{ justifyContent: 'flex-end' }}>
|
||||
<Button
|
||||
size="small"
|
||||
className="nodrag"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => setPainting(addPainting('DMXAPIPaintings', getNewPainting()))}>
|
||||
<Button size="small" className="nodrag" icon={<PlusOutlined />} onClick={createNewPainting}>
|
||||
{t('paintings.button.new.image')}
|
||||
</Button>
|
||||
</NavbarRight>
|
||||
@ -735,15 +790,20 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
<LeftContainer>
|
||||
<ProviderTitleContainer>
|
||||
<SettingTitle style={{ marginBottom: 5 }}>{t('common.provider')}</SettingTitle>
|
||||
<SettingHelpLink target="_blank" href={COURSE_URL}>
|
||||
{t('paintings.paint_course')}
|
||||
<div>
|
||||
<SettingHelpLink target="_blank" href={COURSE_URL}>
|
||||
{t('paintings.paint_course')}
|
||||
</SettingHelpLink>
|
||||
<SettingHelpLink target="_blank" href={TOP_UP_URL}>
|
||||
{t('paintings.top_up')}
|
||||
</SettingHelpLink>
|
||||
<ProviderLogo
|
||||
shape="square"
|
||||
src={getProviderLogo(dmxapiProvider.id)}
|
||||
size={16}
|
||||
style={{ marginLeft: 5 }}
|
||||
/>
|
||||
</SettingHelpLink>
|
||||
</div>
|
||||
</ProviderTitleContainer>
|
||||
<Select value={providerOptions[2].value} onChange={handleProviderChange} style={{ marginBottom: 15 }}>
|
||||
{providerOptions.map((provider) => (
|
||||
@ -793,23 +853,66 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
})}
|
||||
</Select>
|
||||
|
||||
<SettingTitle style={{ marginBottom: 5, marginTop: 15 }}>{t('paintings.image.size')}</SettingTitle>
|
||||
<Select
|
||||
value={isCustomSize ? 'custom' : painting.image_size}
|
||||
onChange={(value) => onSelectImageSize(value)}
|
||||
style={{ width: '100%' }}>
|
||||
{(() => {
|
||||
const currentModel = allModels.find((m) => m.id === painting.model)
|
||||
const modelImageSizes = currentModel?.image_sizes || []
|
||||
|
||||
// 直接使用模型返回的image_sizes数据,包含label和value
|
||||
return modelImageSizes.map((size) => {
|
||||
return (
|
||||
<Select.Option key={size.value} value={size.value}>
|
||||
<HStack style={{ alignItems: 'center', gap: 8 }}>
|
||||
<span>{size.label}</span>
|
||||
</HStack>
|
||||
</Select.Option>
|
||||
)
|
||||
})
|
||||
})()}
|
||||
{/* 检查当前模型是否支持自定义尺寸 */}
|
||||
{allModels.find((m) => m.id === painting.model)?.is_custom_size && (
|
||||
<Select.Option value="custom" key="custom">
|
||||
<HStack style={{ alignItems: 'center', gap: 8 }}>
|
||||
<span>{t('paintings.custom_size')}</span>
|
||||
</HStack>
|
||||
</Select.Option>
|
||||
)}
|
||||
</Select>
|
||||
|
||||
{/* 自定义尺寸输入框 */}
|
||||
{isCustomSize && allModels.find((m) => m.id === painting.model)?.is_custom_size && (
|
||||
<div style={{ marginTop: 10 }}>
|
||||
<HStack style={{ gap: 8, alignItems: 'center' }}>
|
||||
<InputNumber
|
||||
placeholder="W"
|
||||
value={customWidth}
|
||||
controls={false}
|
||||
onChange={(value) => onCustomSizeChange(value, 'width')}
|
||||
min={parseInt(allModels.find((m) => m.id === painting.model)?.min_image_size || '512')}
|
||||
max={parseInt(allModels.find((m) => m.id === painting.model)?.max_image_size || '2048')}
|
||||
style={{ width: 80, flex: 1 }}
|
||||
/>
|
||||
<span style={{ color: 'var(--color-text-2)', fontSize: '12px' }}>x</span>
|
||||
<InputNumber
|
||||
placeholder="H"
|
||||
value={customHeight}
|
||||
controls={false}
|
||||
onChange={(value) => onCustomSizeChange(value, 'height')}
|
||||
min={parseInt(allModels.find((m) => m.id === painting.model)?.min_image_size || 512)}
|
||||
max={parseInt(allModels.find((m) => m.id === painting.model)?.max_image_size || 2048)}
|
||||
style={{ width: 80, flex: 1 }}
|
||||
/>
|
||||
<span style={{ color: 'var(--color-text-3)', fontSize: '11px' }}>px</span>
|
||||
</HStack>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{painting.generationMode === generationModeType.GENERATION && (
|
||||
<>
|
||||
<SettingTitle style={{ marginBottom: 5, marginTop: 15 }}>{t('paintings.image.size')}</SettingTitle>
|
||||
<Radio.Group
|
||||
value={painting.image_size}
|
||||
onChange={(e) => onSelectImageSize(e.target.value)}
|
||||
style={{ display: 'flex' }}>
|
||||
{IMAGE_SIZES.map((size) => (
|
||||
<RadioButton value={size.value} key={size.value}>
|
||||
<VStack alignItems="center">
|
||||
<ImageSizeImage src={size.icon} theme={theme} />
|
||||
<span>{size.label}</span>
|
||||
</VStack>
|
||||
</RadioButton>
|
||||
))}
|
||||
</Radio.Group>
|
||||
|
||||
<SettingTitle style={{ marginBottom: 5, marginTop: 15 }}>
|
||||
{t('paintings.seed')}
|
||||
<Tooltip title={t('paintings.seed_desc_tip')}>
|
||||
@ -896,7 +999,7 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
selectedPainting={painting}
|
||||
onSelectPainting={onSelectPainting}
|
||||
onDeletePainting={onDeletePainting}
|
||||
onNewPainting={() => setPainting(addPainting('DMXAPIPaintings', getNewPainting()))}
|
||||
onNewPainting={createNewPainting}
|
||||
/>
|
||||
</ContentContainer>
|
||||
</Container>
|
||||
@ -991,22 +1094,6 @@ const ToolbarMenu = styled.div`
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
`
|
||||
|
||||
const ImageSizeImage = styled.img<{ theme: string }>`
|
||||
filter: ${({ theme }) => (theme === 'dark' ? 'invert(100%)' : 'none')};
|
||||
margin-top: 8px;
|
||||
`
|
||||
|
||||
const RadioButton = styled(Radio.Button)`
|
||||
width: 30px;
|
||||
height: 55px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
`
|
||||
|
||||
const InfoIcon = styled(Info)`
|
||||
margin-left: 5px;
|
||||
cursor: help;
|
||||
@ -1078,8 +1165,11 @@ const EmptyImgBox = styled.div`
|
||||
const EmptyImg = styled.div<{ bgUrl?: string }>`
|
||||
width: 70vh;
|
||||
height: 70vh;
|
||||
background-size: cover;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-image: ${(props) => (props.bgUrl ? `url(${props.bgUrl})` : `url(${DMXAPIToImg})`)};
|
||||
background-color: #ffffff;
|
||||
`
|
||||
|
||||
const LoadTextWrap = styled.div`
|
||||
|
||||
@ -1,9 +1,3 @@
|
||||
import ImageSize1_1 from '@renderer/assets/images/paintings/image-size-1-1.svg'
|
||||
import ImageSize1_2 from '@renderer/assets/images/paintings/image-size-1-2.svg'
|
||||
import ImageSize3_2 from '@renderer/assets/images/paintings/image-size-3-2.svg'
|
||||
import ImageSize3_4 from '@renderer/assets/images/paintings/image-size-3-4.svg'
|
||||
import ImageSize9_16 from '@renderer/assets/images/paintings/image-size-9-16.svg'
|
||||
import ImageSize16_9 from '@renderer/assets/images/paintings/image-size-16-9.svg'
|
||||
import { uuid } from '@renderer/utils'
|
||||
import { t } from 'i18next'
|
||||
|
||||
@ -15,6 +9,13 @@ export type DMXApiModelData = {
|
||||
provider: string
|
||||
name: string
|
||||
price: string
|
||||
image_sizes: Array<{
|
||||
label: string
|
||||
value: string
|
||||
}>
|
||||
is_custom_size: boolean
|
||||
max_image_size?: number
|
||||
min_image_size?: number
|
||||
}
|
||||
|
||||
// 模型分组类型
|
||||
@ -54,41 +55,10 @@ export const STYLE_TYPE_OPTIONS = [
|
||||
{ label: '巴洛克', value: '巴洛克' }
|
||||
]
|
||||
|
||||
export const IMAGE_SIZES = [
|
||||
{
|
||||
label: '1:1',
|
||||
value: '1328x1328',
|
||||
icon: ImageSize1_1
|
||||
},
|
||||
{
|
||||
label: '1:2',
|
||||
value: '800x1600',
|
||||
icon: ImageSize1_2
|
||||
},
|
||||
{
|
||||
label: '3:2',
|
||||
value: '1584x1056',
|
||||
icon: ImageSize3_2
|
||||
},
|
||||
{
|
||||
label: '3:4',
|
||||
value: '1104x1472',
|
||||
icon: ImageSize3_4
|
||||
},
|
||||
{
|
||||
label: '16:9',
|
||||
value: '1664x936',
|
||||
icon: ImageSize16_9
|
||||
},
|
||||
{
|
||||
label: '9:16',
|
||||
value: '936x1664',
|
||||
icon: ImageSize9_16
|
||||
}
|
||||
]
|
||||
|
||||
export const COURSE_URL = 'http://seedream.dmxapi.cn/'
|
||||
|
||||
export const TOP_UP_URL = 'https://www.dmxapi.cn/topup'
|
||||
|
||||
export const DEFAULT_PAINTING: DmxapiPainting = {
|
||||
id: uuid(),
|
||||
urls: [],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user