/** * 测试脚本:使用素材图片生成电商图片 * 运行方式: 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);