mirror of
https://ghproxy.net/https://github.com/skylarGW/ai-image-generator.git
synced 2025-08-17 19:21:11 +08:00
340 lines
14 KiB
JavaScript
340 lines
14 KiB
JavaScript
// AI图片生成服务类
|
||
class AIImageService {
|
||
constructor() {
|
||
this.apiKey = null;
|
||
this.currentService = API_CONFIG.defaultService;
|
||
this.generationQueue = [];
|
||
this.isGenerating = false;
|
||
}
|
||
|
||
// 设置API密钥
|
||
setApiKey(service, apiKey) {
|
||
this.apiKey = apiKey;
|
||
this.currentService = service;
|
||
localStorage.setItem(`${service}_api_key`, apiKey);
|
||
}
|
||
|
||
// 获取存储的API密钥
|
||
getStoredApiKey(service) {
|
||
return localStorage.getItem(`${service}_api_key`);
|
||
}
|
||
|
||
// 构建提示词
|
||
buildPrompt(formData) {
|
||
let prompt = formData.description || '';
|
||
|
||
// 如果没有描述,根据其他信息构建基础提示词
|
||
if (!prompt.trim()) {
|
||
prompt = '高质量商业图片';
|
||
}
|
||
|
||
// 添加风格信息
|
||
if (formData.style.type) {
|
||
const styleMap = {
|
||
'minimalist': '简约现代风格, 干净简洁的设计',
|
||
'luxury': '奢华高端风格, 精致优雅的质感',
|
||
'lifestyle': '生活方式风格, 自然真实的场景',
|
||
'product-focus': '产品聚焦风格, 突出产品特色',
|
||
'seasonal': '季节主题风格, 应季的氛围感'
|
||
};
|
||
prompt += `, ${styleMap[formData.style.type]}`;
|
||
}
|
||
|
||
// 添加色彩方案
|
||
if (formData.style.colorScheme) {
|
||
const colorMap = {
|
||
'warm': '暖色调配色方案, 温暖舒适的色彩',
|
||
'cool': '冷色调配色方案, 清爽专业的色彩',
|
||
'neutral': '中性色调配色方案, 平衡和谐的色彩',
|
||
'vibrant': '鲜艳色彩配色方案, 活力四射的色彩',
|
||
'monochrome': '单色调配色方案, 统一协调的色彩'
|
||
};
|
||
prompt += `, ${colorMap[formData.style.colorScheme]}`;
|
||
}
|
||
|
||
// 添加平台优化信息
|
||
if (formData.platforms.length > 0) {
|
||
prompt += ', 适合电商平台展示';
|
||
|
||
const platformOptimizations = [];
|
||
if (formData.platforms.includes('tiktok')) {
|
||
platformOptimizations.push('适合短视频展示, 动感有趣');
|
||
}
|
||
if (formData.platforms.includes('instagram')) {
|
||
platformOptimizations.push('适合社交媒体分享, 视觉冲击力强');
|
||
}
|
||
if (formData.platforms.includes('amazon')) {
|
||
platformOptimizations.push('适合产品展示, 清晰的产品细节');
|
||
}
|
||
if (formData.platforms.includes('temu')) {
|
||
platformOptimizations.push('适合跨境电商, 国际化视觉风格');
|
||
}
|
||
|
||
if (platformOptimizations.length > 0) {
|
||
prompt += ', ' + platformOptimizations.join(', ');
|
||
}
|
||
}
|
||
|
||
// 添加目标受众信息
|
||
if (formData.targetAudience && formData.targetAudience.trim()) {
|
||
prompt += `, 面向${formData.targetAudience}的视觉设计`;
|
||
}
|
||
|
||
// 添加尺寸和质量要求
|
||
const { width, height } = formData.dimensions;
|
||
if (width && height) {
|
||
if (width === height) {
|
||
prompt += ', 方形构图';
|
||
} else if (width > height) {
|
||
prompt += ', 横向构图';
|
||
} else {
|
||
prompt += ', 竖向构图';
|
||
}
|
||
}
|
||
|
||
// 添加专业质量描述
|
||
prompt += ', 高质量摄影, 专业打光, 4K分辨率, 商业用途, 精美细节';
|
||
|
||
console.log('构建的完整提示词:', prompt);
|
||
return prompt;
|
||
}
|
||
|
||
// 使用Stability AI生成图片
|
||
async generateWithStability(prompt, params) {
|
||
const response = await fetch(API_CONFIG.services.stability.endpoint, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'Authorization': `Bearer ${this.apiKey}`,
|
||
'Accept': 'application/json'
|
||
},
|
||
body: JSON.stringify({
|
||
text_prompts: [
|
||
{
|
||
text: prompt,
|
||
weight: 1
|
||
}
|
||
],
|
||
cfg_scale: params.cfg_scale || 7,
|
||
height: params.height || 1024,
|
||
width: params.width || 1024,
|
||
samples: params.samples || 1,
|
||
steps: params.steps || 30,
|
||
style_preset: 'photographic'
|
||
})
|
||
});
|
||
|
||
if (!response.ok) {
|
||
const error = await response.json();
|
||
throw new Error(`Stability AI错误: ${error.message || response.statusText}`);
|
||
}
|
||
|
||
const result = await response.json();
|
||
return result.artifacts.map(artifact => ({
|
||
url: `data:image/png;base64,${artifact.base64}`,
|
||
seed: artifact.seed
|
||
}));
|
||
}
|
||
|
||
// 使用OpenAI DALL-E生成图片
|
||
async generateWithOpenAI(prompt, params) {
|
||
const response = await fetch(API_CONFIG.services.openai.endpoint, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'Authorization': `Bearer ${this.apiKey}`
|
||
},
|
||
body: JSON.stringify({
|
||
prompt: prompt,
|
||
n: params.samples || 1,
|
||
size: `${params.width || 1024}x${params.height || 1024}`,
|
||
response_format: 'url'
|
||
})
|
||
});
|
||
|
||
if (!response.ok) {
|
||
const error = await response.json();
|
||
throw new Error(`OpenAI错误: ${error.error?.message || response.statusText}`);
|
||
}
|
||
|
||
const result = await response.json();
|
||
return result.data.map(item => ({
|
||
url: item.url,
|
||
revised_prompt: item.revised_prompt
|
||
}));
|
||
}
|
||
|
||
// 模拟图片生成(用于演示)
|
||
async simulateGeneration(prompt, params) {
|
||
// 模拟API调用延迟
|
||
await new Promise(resolve => setTimeout(resolve, 3000));
|
||
|
||
// 根据提示词内容选择合适的演示图片
|
||
const demoImages = this.selectDemoImages(prompt);
|
||
|
||
// 返回模拟结果
|
||
return demoImages.map((imageUrl, index) => ({
|
||
url: imageUrl,
|
||
prompt: prompt,
|
||
seed: Math.floor(Math.random() * 1000000),
|
||
generated_at: new Date().toISOString(),
|
||
demo_note: '这是演示模式生成的图片,实际AI生成会更符合您的需求'
|
||
}));
|
||
}
|
||
|
||
// 根据提示词选择合适的演示图片
|
||
selectDemoImages(prompt) {
|
||
const lowerPrompt = prompt.toLowerCase();
|
||
|
||
// 定义不同类型的演示图片
|
||
const imageCategories = {
|
||
// 人物相关
|
||
people: [
|
||
'https://images.unsplash.com/photo-1544005313-94ddf0286df2?w=1024&h=1024&fit=crop',
|
||
'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=1024&h=1024&fit=crop',
|
||
'https://images.unsplash.com/photo-1517841905240-472988babdf9?w=1024&h=1024&fit=crop'
|
||
],
|
||
// 运动相关
|
||
sports: [
|
||
'https://images.unsplash.com/photo-1622279457486-62dcc4a431d6?w=1024&h=1024&fit=crop',
|
||
'https://images.unsplash.com/photo-1551698618-1dfe5d97d256?w=1024&h=1024&fit=crop',
|
||
'https://images.unsplash.com/photo-1554068865-24cecd4e34b8?w=1024&h=1024&fit=crop'
|
||
],
|
||
// 产品相关
|
||
product: [
|
||
'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=1024&h=1024&fit=crop',
|
||
'https://images.unsplash.com/photo-1572635196237-14b3f281503f?w=1024&h=1024&fit=crop',
|
||
'https://images.unsplash.com/photo-1560472354-b33ff0c44a43?w=1024&h=1024&fit=crop'
|
||
],
|
||
// 时尚相关
|
||
fashion: [
|
||
'https://images.unsplash.com/photo-1515372039744-b8f02a3ae446?w=1024&h=1024&fit=crop',
|
||
'https://images.unsplash.com/photo-1509631179647-0177331693ae?w=1024&h=1024&fit=crop',
|
||
'https://images.unsplash.com/photo-1445205170230-053b83016050?w=1024&h=1024&fit=crop'
|
||
],
|
||
// 生活方式
|
||
lifestyle: [
|
||
'https://images.unsplash.com/photo-1513475382585-d06e58bcb0e0?w=1024&h=1024&fit=crop',
|
||
'https://images.unsplash.com/photo-1522202176988-66273c2fd55f?w=1024&h=1024&fit=crop',
|
||
'https://images.unsplash.com/photo-1511632765486-a01980e01a18?w=1024&h=1024&fit=crop'
|
||
],
|
||
// 默认商业图片
|
||
business: [
|
||
'https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?w=1024&h=1024&fit=crop',
|
||
'https://images.unsplash.com/photo-1553062407-98eeb64c6a62?w=1024&h=1024&fit=crop',
|
||
'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=1024&h=1024&fit=crop'
|
||
]
|
||
};
|
||
|
||
// 根据关键词匹配图片类型
|
||
let selectedCategory = 'business'; // 默认类型
|
||
|
||
if (lowerPrompt.includes('tennis') || lowerPrompt.includes('sport') || lowerPrompt.includes('运动') || lowerPrompt.includes('网球')) {
|
||
selectedCategory = 'sports';
|
||
} else if (lowerPrompt.includes('student') || lowerPrompt.includes('people') || lowerPrompt.includes('person') || lowerPrompt.includes('女性') || lowerPrompt.includes('男性') || lowerPrompt.includes('人物')) {
|
||
selectedCategory = 'people';
|
||
} else if (lowerPrompt.includes('product') || lowerPrompt.includes('商品') || lowerPrompt.includes('产品')) {
|
||
selectedCategory = 'product';
|
||
} else if (lowerPrompt.includes('fashion') || lowerPrompt.includes('dress') || lowerPrompt.includes('clothing') || lowerPrompt.includes('时尚') || lowerPrompt.includes('服装')) {
|
||
selectedCategory = 'fashion';
|
||
} else if (lowerPrompt.includes('lifestyle') || lowerPrompt.includes('生活') || lowerPrompt.includes('日常')) {
|
||
selectedCategory = 'lifestyle';
|
||
}
|
||
|
||
console.log(`根据提示词"${prompt}"选择了图片类型: ${selectedCategory}`);
|
||
|
||
// 返回选中类型的图片(随机选择1-2张)
|
||
const images = imageCategories[selectedCategory];
|
||
const numImages = Math.random() > 0.7 ? 2 : 1; // 30%概率生成2张图片
|
||
|
||
const selectedImages = [];
|
||
for (let i = 0; i < numImages; i++) {
|
||
const randomIndex = Math.floor(Math.random() * images.length);
|
||
selectedImages.push(images[randomIndex]);
|
||
}
|
||
|
||
return selectedImages;
|
||
}
|
||
|
||
// 主要的图片生成方法
|
||
async generateImages(formData) {
|
||
try {
|
||
this.isGenerating = true;
|
||
|
||
// 构建提示词
|
||
const prompt = this.buildPrompt(formData);
|
||
|
||
// 准备参数
|
||
const params = {
|
||
width: formData.dimensions.width,
|
||
height: formData.dimensions.height,
|
||
samples: 1, // 先生成1张,后续可以让用户选择数量
|
||
...API_CONFIG.defaultParams
|
||
};
|
||
|
||
console.log('生成参数:', { prompt, params, service: this.currentService });
|
||
|
||
let results;
|
||
|
||
// 根据当前服务选择生成方法
|
||
if (this.apiKey && this.currentService === 'stability') {
|
||
results = await this.generateWithStability(prompt, params);
|
||
} else if (this.apiKey && this.currentService === 'openai') {
|
||
results = await this.generateWithOpenAI(prompt, params);
|
||
} else {
|
||
// 如果没有API密钥,使用模拟生成
|
||
console.log('使用模拟生成模式');
|
||
results = await this.simulateGeneration(prompt, params);
|
||
}
|
||
|
||
// 添加元数据
|
||
const enhancedResults = results.map(result => ({
|
||
...result,
|
||
id: 'img_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9),
|
||
prompt: prompt,
|
||
dimensions: params,
|
||
service: this.currentService,
|
||
created_at: new Date().toISOString(),
|
||
formData: formData // 保存原始表单数据用于后续分析
|
||
}));
|
||
|
||
// 保存到本地存储
|
||
this.saveGenerationHistory(enhancedResults);
|
||
|
||
return enhancedResults;
|
||
|
||
} catch (error) {
|
||
console.error('图片生成失败:', error);
|
||
throw error;
|
||
} finally {
|
||
this.isGenerating = false;
|
||
}
|
||
}
|
||
|
||
// 保存生成历史
|
||
saveGenerationHistory(results) {
|
||
const history = JSON.parse(localStorage.getItem('generation_history') || '[]');
|
||
history.push(...results);
|
||
|
||
// 只保留最近100条记录
|
||
if (history.length > 100) {
|
||
history.splice(0, history.length - 100);
|
||
}
|
||
|
||
localStorage.setItem('generation_history', JSON.stringify(history));
|
||
}
|
||
|
||
// 获取生成历史
|
||
getGenerationHistory() {
|
||
return JSON.parse(localStorage.getItem('generation_history') || '[]');
|
||
}
|
||
|
||
// 检查服务状态
|
||
async checkServiceStatus(service) {
|
||
// 这里可以添加服务健康检查
|
||
return { status: 'available', service: service };
|
||
}
|
||
}
|
||
|
||
// 创建全局实例
|
||
const aiImageService = new AIImageService();
|