diff --git a/components/ai/AiChooseFood.vue b/components/ai/AiChooseFood.vue new file mode 100644 index 0000000..d3bce53 --- /dev/null +++ b/components/ai/AiChooseFood.vue @@ -0,0 +1,144 @@ + + + + + + 🥘 先选一下食材 + + + + 🥬 菜菜们 + + + + {{ item.emoji }} + + + + {{ item.name }} + + + + + + 🥩 肉肉们 + + + + {{ item.emoji }} + {{ item.name }} + + + + + + 🍚 主食也要一起下锅吗?(不选也行) + + + + {{ item.emoji }} + {{ item.name }} + + + + + + + + + + + 做美食 🥘 + + + + + 🍲 来看看制作出的美食吧! + + + + + + + + diff --git a/components/common/SearchRecipe.vue b/components/common/SearchRecipe.vue index aefcb3d..ef6c6fa 100644 --- a/components/common/SearchRecipe.vue +++ b/components/common/SearchRecipe.vue @@ -25,7 +25,7 @@ const filteredRecipes = computedAsync(async () => { + + + + + diff --git a/pages/ai.vue b/pages/ai.vue new file mode 100644 index 0000000..ef895ef --- /dev/null +++ b/pages/ai.vue @@ -0,0 +1,25 @@ + + + + + + + + + + + 好的,今天我们来做菜! + + + + diff --git a/server/api/README.md b/server/api/README.md new file mode 100644 index 0000000..176c0b4 --- /dev/null +++ b/server/api/README.md @@ -0,0 +1,3 @@ +# SD API + +- [SD WebUI API](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/API) diff --git a/server/api/recipes/image/generate.ts b/server/api/recipes/image/generate.ts new file mode 100644 index 0000000..60bc4a1 --- /dev/null +++ b/server/api/recipes/image/generate.ts @@ -0,0 +1,70 @@ +// http://localhost:3001/api/recipes/image/generate + +import { meat, staple, vegetable } from '~/data/food' + +// const sdBaseUrl = 'http://30.30.168.63:7860/' +const sdBaseUrl = 'https://85db1802ae46e57aab.gradio.live/' + +const payload = { + // denoising_strength: 0, + prompt: 'food', // 提示词 + negative_prompt: '', // 反向提示词 + seed: -1, // 种子,随机数 + batch_size: 2, // 每次张数 + n_iter: 1, // 生成批次 + steps: 50, // 生成步数 + cfg_scale: 7, // 关键词相关性 + width: 512, // 宽度 + height: 512, // 高度 + restore_faces: false, // 脸部修复 + tiling: false, // 可平埔 + // override_settings: { + // sd_model_checkpoint: 'wlop-any.ckpt [7331f3bc87]', + // }, // 一般用于修改本次的生成图片的stable diffusion 模型,用法需保持一致 + // script_args: [ + // 0, + // true, + // true, + // 'LoRA', + // 'dingzhenlora_v1(fa7c1732cc95)', + // 1, + // 1, + // ], // 一般用于lora模型或其他插件参数,如示例,我放入了一个lora模型, 1,1为两个权重值,一般只用到前面的权重值1 + sampler_index: 'Euler', // 采样方法 +} + +// with api /sdapi/v1/txt2img + +export interface Txt2ImgResponse { + images: string[] +} + +const stuffItems = [ + ...vegetable, + ...meat, + ...staple, +] + +export default defineEventHandler(async (e) => { + const body = await readBody(e) + + const zhFoods = body.foods as string[] + const enFoods = zhFoods.map((food) => { + const item = stuffItems.find(item => item.name === food) + if (item) + return item.en + return '' + }) + + // TODO: 过滤 prompt 只能是食材 + payload.prompt = `,food focus,transparent background,${enFoods.join(',')}` + + // console.log(payload.prompt) + + const data = await $fetch('/sdapi/v1/txt2img', { + baseURL: sdBaseUrl, + body: payload, + method: 'POST', + }) + return data +}) diff --git a/types/recipe.ts b/types/recipe.ts index 7fcb982..2e2437c 100644 --- a/types/recipe.ts +++ b/types/recipe.ts @@ -66,4 +66,9 @@ export interface StuffItem { * 显示标签 */ label?: string + /** + * 英文名称, for ai keyword + * @example 'potato' + */ + en?: string } diff --git a/utils/api/index.ts b/utils/api/index.ts new file mode 100644 index 0000000..05ce15d --- /dev/null +++ b/utils/api/index.ts @@ -0,0 +1,14 @@ +// filter prompt +export async function generateRecipeImage(foods: string[]) { + return $fetch('/api/recipes/image/generate', { + method: 'POST', + body: { + foods, + }, + }) +} + +export async function getRecipeImage(foods: string[]) { + const data = await generateRecipeImage(foods) + return `data:image/png;base64,${data.images[0]}` +}
+ 好的,今天我们来做菜! +