Upload latest code and optimized prompts (v6)

This commit is contained in:
tony
2025-12-14 19:52:54 +08:00
commit f5cb1042ae
42 changed files with 15302 additions and 0 deletions

359
test-generate.js Normal file
View File

@@ -0,0 +1,359 @@
/**
* 测试脚本:使用素材图片生成电商图片
* 运行方式: node test-generate.js
*/
require('dotenv').config();
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
// 配置
const SERVER_URL = 'http://localhost:3000';
const OUTPUT_DIR = path.join(__dirname, 'output');
const MATERIAL_DIR = path.join(__dirname, '素材/素材/已有的素材');
// R2客户端
const r2Client = new S3Client({
region: 'auto',
endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
credentials: {
accessKeyId: process.env.R2_ACCESS_KEY_ID,
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
},
forcePathStyle: true,
});
/**
* 上传图片到R2
*/
async function uploadToR2(filePath) {
const fileName = `test-${Date.now()}-${path.basename(filePath)}`;
const fileBuffer = fs.readFileSync(filePath);
const contentType = filePath.endsWith('.png') ? 'image/png' : 'image/jpeg';
const command = new PutObjectCommand({
Bucket: process.env.R2_BUCKET_NAME || 'ai-flow',
Key: fileName,
Body: fileBuffer,
ContentType: contentType,
});
await r2Client.send(command);
const publicUrl = process.env.R2_PUBLIC_DOMAIN
? `${process.env.R2_PUBLIC_DOMAIN}/${fileName}`
: `https://pub-${process.env.R2_ACCOUNT_ID}.r2.dev/${fileName}`;
console.log(` 上传成功: ${fileName}`);
return publicUrl;
}
/**
* 下载图片到本地
*/
async function downloadImage(url, outputPath) {
try {
const response = await axios.get(url, { responseType: 'arraybuffer', timeout: 60000 });
fs.writeFileSync(outputPath, response.data);
console.log(` 下载成功: ${path.basename(outputPath)}`);
return true;
} catch (error) {
console.error(` 下载失败: ${error.message}`);
return false;
}
}
/**
* 主函数
*/
async function main() {
console.log('\n========================================');
console.log('Touchdog 电商图片生成测试');
console.log('========================================\n');
// 确保输出目录存在
if (!fs.existsSync(OUTPUT_DIR)) {
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
}
// 1. 获取素材图片
console.log('📁 Step 1: 读取素材图片...');
const materialFiles = fs.readdirSync(MATERIAL_DIR)
.filter(f => /\.(jpg|jpeg|png)$/i.test(f))
.slice(0, 3); // 取前3张作为参考
console.log(` 找到 ${materialFiles.length} 张素材图片`);
// 2. 上传素材到R2
console.log('\n📤 Step 2: 上传素材到R2...');
const refImageUrls = [];
for (const file of materialFiles) {
try {
const filePath = path.join(MATERIAL_DIR, file);
const url = await uploadToR2(filePath);
refImageUrls.push(url);
} catch (error) {
console.error(` 上传失败 ${file}: ${error.message}`);
}
}
if (refImageUrls.length === 0) {
console.error('❌ 没有成功上传任何参考图片,退出');
process.exit(1);
}
console.log(` 成功上传 ${refImageUrls.length} 张参考图`);
// 3. 构建SKU数据
console.log('\n📝 Step 3: 构建SKU数据...');
const sku = {
sku_id: 'TD-EC-TEST-001',
product_name: 'Cat Soft Cone Collar',
product_name_cn: '伊丽莎白圈',
brand: 'Touchdog',
color: {
name: 'Ice Blue',
name_cn: '冰蓝色',
series: 'Iridescent',
hex: '#B0E0E6',
edge_color: '#7FDBDB'
},
selling_points: [
{
key: 'lightweight',
title_en: 'LIGHTER THAN AN EGG',
title_cn: '极致轻盈',
value: '65g',
description_en: 'Cloud-light comfort at only 65g',
visual_prompt: 'product shown next to an egg for size comparison'
},
{
key: 'waterproof',
title_en: 'WATERPROOF & EASY WIPE',
title_cn: '防水易清洁',
description_en: 'Waterproof PU fabric, stains wipe clean instantly',
visual_prompt: 'water droplets beading on the surface'
},
{
key: 'breathable',
title_en: 'BREATHABLE COTTON LINING',
title_cn: '舒适亲肤',
description_en: 'Soft cotton inner layer, comfortable for extended wear',
visual_prompt: 'close-up of soft cotton inner lining'
},
{
key: 'adjustable',
title_en: 'ADJUSTABLE STRAP',
title_cn: '可调节',
description_en: '3-second on/off, adjustable velcro',
visual_prompt: 'velcro strap being adjusted'
}
],
specs: {
weight: '65g',
depth_cm: '24.5',
sizes: ['XS', 'S', 'M', 'L', 'XL'],
materials: {
outer: 'Durable Waterproof PU',
inner: '95% Cotton + 5% Spandex'
}
},
use_cases: [
{ name_en: 'Postoperative Care', name_cn: '术后恢复' },
{ name_en: 'Eye Drop Application', name_cn: '驱虫护理' },
{ name_en: 'Nail Trimming', name_cn: '指甲修剪' },
{ name_en: 'Grooming', name_cn: '美容护理' }
],
ref_images: refImageUrls
};
console.log(' SKU数据准备完成');
console.log(` 参考图: ${refImageUrls.length}`);
// 4. 调用生成API (只生成前3张测试)
console.log('\n🎨 Step 4: 调用AI生图API...');
console.log(' (为节省时间仅生成3张测试图)\n');
// 直接调用图像生成API进行测试
const testPrompts = [
{
id: 'Main_01',
type: '场景首图+卖点摘要',
prompt: `Professional Amazon main image for Touchdog Cat Soft Cone Collar, 1:1 square format.
COMPOSITION:
- TOP 60%: A beautiful Ragdoll cat wearing the Ice Blue (#B0E0E6) soft cone collar in a cozy modern home interior with warm wood shelving. Natural soft lighting from window. Cat looks comfortable and relaxed. The cone collar is soft fabric with petal-like segments.
- BOTTOM 40%: Light blue (#B0E0E6) rounded banner with title "DESIGNED FOR COMFORTABLE RECOVERY" in navy blue text. Below: three small circular images showing:
1. Product next to an egg showing 65g weight - "LIGHTER THAN AN EGG"
2. Water droplets on surface - "WATERPROOF & EASY WIPE"
3. Soft cotton lining detail - "BREATHABLE COTTON LINING"
PRODUCT REQUIREMENTS:
- Soft cone collar with petal-like fabric segments, NOT rigid plastic
- Color: Ice Blue (#B0E0E6) with teal edge binding (#7FDBDB)
- Embroidered "TOUCHDOG®" logo visible on right petal (2-3 o'clock position)
- Waterproof PU outer, soft cotton inner visible at edges
STYLE: Clean, professional Amazon listing photo. Warm home aesthetic. High-end pet product photography.
--ar 1:1`
},
{
id: 'Main_02',
type: '产品平铺+细节放大',
prompt: `Professional Amazon product detail image for Touchdog Cat Soft Cone Collar, 1:1 square format.
COMPOSITION:
- CENTER: Ice Blue (#B0E0E6) soft cone collar displayed flat from above on clean white background. Shows full petal-like segment structure.
- Two circular detail callout bubbles with thin lines pointing to product:
1. Left callout: "DURABLE WATERPROOF PU LAYER" - showing the smooth outer texture
2. Right callout: "DOUBLE-LAYER COMFORT" - showing the soft ribbed edge binding in teal (#7FDBDB)
PRODUCT REQUIREMENTS:
- Soft fabric cone with 8-10 petal segments radiating from center
- Visible velcro closure strap
- "TOUCHDOG®" embroidered logo on right side
- Color: Ice Blue (#B0E0E6) main, teal binding
STYLE: Clean white background product photography. Professional Amazon listing style. Even studio lighting.
--ar 1:1`
},
{
id: 'APlus_01',
type: '品牌Banner',
prompt: `Professional Amazon A+ brand banner image for Touchdog Cat Soft Cone Collar, landscape 970x600 format.
COMPOSITION:
- FULL WIDTH: Warm modern living room scene with a beautiful white cat wearing the Ice Blue soft cone collar, standing gracefully on a light wood surface.
- LEFT SIDE: Large stylized "TOUCHDOG" brand text in coral/pink color with playful font, paw print decorations
- BELOW: "CAT SOFT CONE COLLAR" product name text
PRODUCT REQUIREMENTS:
- Cat wearing Ice Blue (#B0E0E6) soft cone collar
- Petal-like fabric segments visible
- Collar looks soft and comfortable, not rigid
ENVIRONMENT:
- Cozy modern home interior
- Soft natural lighting
- Warm neutral tones (beige, cream, light wood)
- Professional lifestyle photography feel
BRAND ELEMENTS:
- Touchdog logo with heart-shaped dog icon in red
- "wow pretty" tagline
--ar 3:2`
}
];
const results = [];
for (const testPrompt of testPrompts) {
console.log(` 生成 ${testPrompt.id}: ${testPrompt.type}...`);
try {
const payload = {
model: 'gemini-3-pro-image-preview',
prompt: testPrompt.prompt,
n: 1,
size: '1K',
aspect_ratio: testPrompt.id.startsWith('APlus') ? '3:2' : '1:1',
image_urls: refImageUrls
};
const response = await axios.post(
'https://api2img.shubiaobiao.com/v1/images/generations',
payload,
{
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.API_KEY}`
},
timeout: 180000
}
);
// 处理响应 - 可能是URL或base64
const imageData = response.data.data?.[0];
const outputPath = path.join(OUTPUT_DIR, `${sku.sku_id}-${testPrompt.id}.jpg`);
if (imageData?.b64_json) {
// Base64格式 - 直接保存
const imageBuffer = Buffer.from(imageData.b64_json, 'base64');
fs.writeFileSync(outputPath, imageBuffer);
console.log(` 保存成功: ${path.basename(outputPath)}`);
results.push({
id: testPrompt.id,
type: testPrompt.type,
localPath: outputPath,
status: 'success'
});
console.log(`${testPrompt.id} 生成成功`);
} else if (imageData?.url) {
// URL格式 - 下载保存
await downloadImage(imageData.url, outputPath);
results.push({
id: testPrompt.id,
type: testPrompt.type,
url: imageData.url,
localPath: outputPath,
status: 'success'
});
console.log(`${testPrompt.id} 生成成功`);
} else {
throw new Error('No image data in response');
}
// 延迟避免限流
await new Promise(r => setTimeout(r, 2000));
} catch (error) {
console.error(`${testPrompt.id} 生成失败: ${error.message}`);
results.push({
id: testPrompt.id,
type: testPrompt.type,
status: 'failed',
error: error.message
});
}
}
// 5. 输出结果
console.log('\n========================================');
console.log('生成结果汇总');
console.log('========================================');
const successCount = results.filter(r => r.status === 'success').length;
console.log(`\n成功: ${successCount}/${results.length}`);
results.forEach(r => {
const status = r.status === 'success' ? '✓' : '✗';
console.log(` ${status} ${r.id} - ${r.type}`);
if (r.localPath) {
console.log(` 保存位置: ${r.localPath}`);
}
});
console.log(`\n📁 输出目录: ${OUTPUT_DIR}`);
console.log('\n========================================\n');
// 保存结果JSON
fs.writeFileSync(
path.join(OUTPUT_DIR, 'generation-results.json'),
JSON.stringify({ sku, results }, null, 2)
);
}
// 运行
main().catch(console.error);