文章目录
一、项目背景与功能概述
在内容创作、营销、教育等场景中,“图文搭配”已成为提高传播力的重要手段。传统配图往往耗费大量时间,而基于 DALL·E 的文本生成图像(text-to-image)技术,正在改变这一现状。
本文将带你用 Vue 3 构建一个实用型图像生成器,支持以下功能:
- ✅ 文本生成图片,调用 OpenAI DALL·E 接口
- ✅ 推荐关键词快速填充 prompt
- ✅ 多张图片批量展示
- ✅ 支持下载任意生成图片
- ✅ 接口封装、UI 动效、响应式布局等最佳实践
应用场景包括:
- 内容创作者写作配图
- 小程序海报生成
- 电商视觉创意辅助
- AI 绘图爱好者辅助工具
二、技术选型与环境配置
技术栈 | 说明 |
---|---|
Vue 3 + Composition API | 构建核心组件 |
Tailwind CSS | 快速响应式样式 |
Axios | 请求 OpenAI API |
OpenAI Image API | 文本生成图像 |
FileSaver.js | 实现图片下载功能 |
环境准备
- 获取 OpenAI API Key:https://platform.openai.com/account/api-keys
.env
文件中添加密钥配置:
VITE_OPENAI_API_KEY=你的key
- 安装必要依赖:
npm install axios file-saver
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
三、图像生成器组件实现
第一节:封装 DALL·E 请求函数
// utils/image.ts
import axios from 'axios'
const instance = axios.create({
baseURL: 'https://api.openai.com/v1',
headers: {
Authorization: `Bearer ${import.meta.env.VITE_OPENAI_API_KEY}`,
'Content-Type': 'application/json'
}
})
export function generateImages(prompt: string, n = 4, size = '512x512') {
return instance.post('/images/generations', {
prompt,
n,
size
})
}
第二节:图像生成核心组件实现
<template>
<div class="max-w-4xl mx-auto p-6 space-y-6">
<h1 class="text-2xl font-bold">AI 图像生成器</h1>
<!-- 推荐关键词 -->
<div class="flex flex-wrap gap-2">
<span v-for="kw in keywords" :key="kw"
@click="prompt = kw"
class="cursor-pointer bg-blue-100 text-blue-700 px-2 py-1 rounded hover:bg-blue-200 text-sm">
{{ kw }}
</span>
</div>
<!-- 文本输入 -->
<textarea v-model="prompt" rows="3"
class="w-full border rounded p-2"
placeholder="请输入你想生成的图像描述,如:一只在太空中弹吉他的猫" />
<!-- 控制区域 -->
<div class="flex items-center justify-between">
<select v-model="count" class="border px-2 py-1 rounded text-sm">
<option :value="1">1 张</option>
<option :value="2">2 张</option>
<option :value="4">4 张</option>
</select>
<button @click="generate" :disabled="loading"
class="bg-blue-600 text-white px-4 py-1 rounded">
生成图像
</button>
</div>
<!-- 加载状态 -->
<div v-if="loading" class="text-gray-500">生成中,请稍候...</div>
<!-- 图片展示 -->
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-2 gap-4">
<div v-for="(url, idx) in imageUrls" :key="idx" class="relative group">
<img :src="url" class="w-full h-auto rounded shadow" />
<button @click="downloadImage(url)"
class="absolute top-2 right-2 bg-black bg-opacity-50 text-white text-xs px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition">
下载
</button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { generateImages } from '@/utils/image'
import { saveAs } from 'file-saver'
const prompt = ref('')
const count = ref(4)
const imageUrls = ref<string[]>([])
const loading = ref(false)
const keywords = [
'复古风格的海边小屋',
'在火星上野餐的情侣',
'霓虹灯下的未来都市',
'拟人化的狐狸教授',
'太空中的浮动书籍'
]
const generate = async () => {
if (!prompt.value.trim()) return
loading.value = true
imageUrls.value = []
try {
const res = await generateImages(prompt.value, count.value)
imageUrls.value = res.data.data.map((item: any) => item.url)
} catch (e) {
alert('生成失败,请检查 API Key 或网络')
} finally {
loading.value = false
}
}
const downloadImage = async (url: string) => {
const res = await fetch(url)
const blob = await res.blob()
saveAs(blob, `image-${Date.now()}.png`)
}
</script>
四、功能拓展与优化建议(附可实现方案)
以下是一些实用的扩展建议,已附带可落地的实现方案。
1. 分辨率选择功能
用户可以选择不同图像清晰度:
<select v-model="size" class="border px-2 py-1 rounded text-sm">
<option value="256x256">256x256</option>
<option value="512x512">512x512</option>
<option value="1024x1024">1024x1024</option>
</select>
调用 API 时传入:
await generateImages(prompt.value, count.value, size.value)
2. 关键词智能联想(模拟实现)
可以基于 prompt 前缀推荐关键词:
watch(prompt, (val) => {
if (val.startsWith('猫')) {
keywords.value = ['猫在下雨天散步', '穿宇航服的猫', '猫咪艺术风肖像']
} else if (val.startsWith('太空')) {
keywords.value = ['太空舱内的宇航员', '在太空中弹吉他的猩猩']
}
})
也可以接入 ChatGPT 接口实现自动联想提示。
3. 图片美化功能(使用 fabric.js 实现基础画布)
安装依赖:
npm install fabric
在组件中引用:
import { fabric } from 'fabric'
onMounted(() => {
const canvas = new fabric.Canvas('canvas')
fabric.Image.fromURL(imageUrls.value[0], function (img) {
canvas.add(img)
})
})
HTML 结构:
<canvas id="canvas" width="512" height="512"></canvas>
4. 本地记录生成历史(使用 localStorage)
将每次生成记录存入本地:
watch(imageUrls, (newVal) => {
const history = JSON.parse(localStorage.getItem('image-history') || '[]')
localStorage.setItem('image-history', JSON.stringify([...history, ...newVal]))
})
读取历史:
const history = JSON.parse(localStorage.getItem('image-history') || '[]')
并在组件中作为可选 tab 展示。
到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 前端 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~
创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:
点个赞❤️ 让更多人看到优质内容
关注「前端极客探险家」🚀 每周解锁新技巧
收藏文章⭐️ 方便随时查阅
📢 特别提醒:
转载请注明原文链接,商业合作请私信联系
感谢你的阅读!我们下篇文章再见~ 💕