feat: 图生图功能

feat: 参考图片(图生图)选择器
ui: 文件上传(预留) composable
ui: 登录过期提示
ui: 调整部分 ui
This commit is contained in:
2024-03-22 16:34:00 +08:00
parent 75f431d7bf
commit 5d52e8dafa
9 changed files with 295 additions and 32 deletions

View File

@@ -10,6 +10,7 @@ import {useFetchWrapped} from '~/composables/useFetchWrapped';
import type {ResultBlockMeta} from '~/components/aigc/drawing';
import {useHistory} from '~/composables/useHistory';
import {del, set} from 'idb-keyval';
import ReferenceFigureSelector from '~/components/aigc/ReferenceFigureSelector.vue';
useHead({
title: '绘画 | XSH AI',
@@ -52,8 +53,6 @@ const handle_stick_mousedown = (e: MouseEvent, min: number = 240, max: number =
}
}
// const histories = ref<HistoryItem[]>([])
const defaultRatios = [
{
ratio: '1:1',
@@ -177,6 +176,28 @@ const defaultStyles: StyleItem[] = [
value: 116,
},
]
const img2imgStyles: StyleItem[] = [
{
label: '水彩画',
value: 106,
},
{
label: '2.5D',
value: 110,
},
{
label: '日系动漫',
value: 201,
},
{
label: '美系动漫',
value: 202,
},
{
label: '唯美古风',
value: 203,
},
]
const defaultFormSchema = object({
prompt: string().required('请输入提示词'),
@@ -186,6 +207,7 @@ const defaultFormSchema = object({
label: string(),
value: number(),
}).required('请选择风格'),
file: string().nullable(),
})
type DefaultFormSchema = InferType<typeof defaultFormSchema>
@@ -195,6 +217,14 @@ const defaultFormState = reactive({
negative_prompt: '',
resolution: '1024:768',
styles: defaultStyles.find(item => item.value === 401),
file: null,
})
watch(() => defaultFormState.file, (newVal) => {
if (newVal) {
defaultFormState.styles = img2imgStyles[0]
} else {
defaultFormState.styles = defaultStyles.find(item => item.value === 401)
}
})
const onDefaultFormSubmit = (event: FormSubmitEvent<DefaultFormSchema>) => {
@@ -203,24 +233,27 @@ const onDefaultFormSubmit = (event: FormSubmitEvent<DefaultFormSchema>) => {
return
}
generating.value = true
const styleItem = event.data.styles as StyleItem
if (!event.data.file) delete event.data.file
// generate a uuid
const fid = Math.random().toString(36).substring(2)
const meta: ResultBlockMeta = {
cost: '1000',
modal: '混元大模型',
style: styleItem.label,
ratio: event.data.resolution,
datetime: dayjs().unix(),
type: event.data.file ? '智能图生图' : '智能文生图',
}
history.text2img.unshift({
fid,
meta,
prompt: event.data.prompt,
})
const styleItem = event.data.styles as StyleItem
useFetchWrapped<
HunYuan.Text2Img.req & AuthedRequest,
BaseResponse<HunYuan.Text2Img.resp>
>('App.Assistant_HunYuan.TenTextToImg', {
(HunYuan.Text2Img.req | HunYuan.Img2Img.req) & AuthedRequest,
BaseResponse<HunYuan.resp>
>(event.data.file ? 'App.Assistant_HunYuan.TenImgToImg' : 'App.Assistant_HunYuan.TenTextToImg', {
token: loginState.token as string,
user_id: loginState.user.id,
device_id: 'web',
@@ -292,9 +325,18 @@ const onDefaultFormSubmit = (event: FormSubmitEvent<DefaultFormSchema>) => {
resize/>
</UFormGroup>
</OptionBlock>
<OptionBlock icon="i-tabler-library-photo" label="参考图片">
<UFormGroup name="input_image">
<ReferenceFigureSelector
:value="defaultFormState.file"
@update="file => {defaultFormState.file = file; console.log('recv', file)}"
text="选择参考图片" text-on-select="已选择参考图"/>
</UFormGroup>
</OptionBlock>
<OptionBlock icon="i-tabler-photo-hexagon" label="图片风格">
<UFormGroup name="styles">
<USelectMenu v-model="defaultFormState.styles" :options="defaultStyles"></USelectMenu>
<USelectMenu v-model="defaultFormState.styles"
:options="defaultFormState.file ? img2imgStyles : defaultStyles"></USelectMenu>
</UFormGroup>
</OptionBlock>
<OptionBlock icon="i-tabler-article-off" label="图片比例">
@@ -310,7 +352,7 @@ const onDefaultFormSubmit = (event: FormSubmitEvent<DefaultFormSchema>) => {
{{ generating ? '生成中' : '生成' }}
</UButton>
<p class="text-xs text-neutral-400 dark:text-neutral-500 font-bold">
生成即代表您同意<a href="https://baidu.com" target="_blank"
生成即代表您同意<a href="#" target="_blank"
class="underline underline-offset-2">用户许可协议</a>
</p>
</div>
@@ -333,9 +375,9 @@ const onDefaultFormSubmit = (event: FormSubmitEvent<DefaultFormSchema>) => {
<Icon name="i-tabler-photo-hexagon" class="text-7xl text-neutral-300 dark:text-neutral-700"/>
<p class="text-sm text-neutral-500 dark:text-neutral-400">没有记录</p>
</div>
<ResultBlock v-else v-for="(result, k) in history.text2img"
title="文生图" :fid="result.fid" :meta="result.meta"
:prompt="result.prompt" :key="result.fid">
<ResultBlock v-else v-for="(result, k) in history.text2img" :fid="result.fid" :meta="result.meta"
:prompt="result.prompt" :key="result.fid"
@use-reference="file => {defaultFormState.file = file}">
<template #header-right>
<UPopover overlay>
<UButton color="black" size="xs" icon="i-tabler-trash" variant="ghost"></UButton>