Files
amz-pic-flow/test-vision-extract.js

210 lines
6.7 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 测试Vision自动提取产品特征
* 目标验证Vision能否从素材图中自动提取"黄金产品描述"
*/
require('dotenv').config();
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
const API_KEY = 'G9rXx3Ag2Xfa7Gs8zou6t6HqeZ';
const API_BASE = 'https://api.wuyinkeji.com/api';
// 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,
});
async function uploadToR2(filePath) {
const fileName = `vision-test-${Date.now()}-${path.basename(filePath)}`;
const fileBuffer = fs.readFileSync(filePath);
await r2Client.send(new PutObjectCommand({
Bucket: process.env.R2_BUCKET_NAME || 'ai-flow',
Key: fileName,
Body: fileBuffer,
ContentType: filePath.endsWith('.png') ? 'image/png' : 'image/jpeg',
}));
const publicUrl = process.env.R2_PUBLIC_DOMAIN
? `${process.env.R2_PUBLIC_DOMAIN}/${fileName}`
: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com/${process.env.R2_BUCKET_NAME}/${fileName}`;
return publicUrl;
}
// Vision提取产品特征的Prompt
const VISION_EXTRACT_PROMPT = `Analyze this pet recovery cone product image in EXTREME detail.
You MUST extract and output the following information as structured JSON:
{
"color": {
"primary": "<hex code like #C5E8ED>",
"name": "<descriptive name like 'ice blue', 'mint green'>",
"secondary": "<any accent colors>"
},
"shape": {
"type": "<flower/fan/cone/other>",
"petal_count": <number of segments/petals>,
"opening": "<C-shaped/full-circle/other>",
"description": "<detailed shape description>"
},
"material": {
"type": "<PU/fabric/plastic/other>",
"finish": "<glossy/matte/satin>",
"texture": "<smooth/quilted/ribbed>"
},
"edge_binding": {
"color": "<color of inner neck edge>",
"material": "<ribbed elastic/fabric/other>"
},
"closure": {
"type": "<velcro/button/snap/other>",
"color": "<white/matching/other>",
"position": "<which petal or location>"
},
"logo": {
"text": "<brand name if visible>",
"style": "<embroidered/printed/tag>",
"position": "<location on product>"
},
"unique_features": [
"<list any distinctive features>"
],
"overall_description": "<2-3 sentence summary for image generation prompt>"
}
Be EXTREMELY precise about colors and structural details. This will be used to generate consistent product images.`;
async function testVisionExtract(imagePath) {
console.log('📤 上传图片到R2...');
const imageUrl = await uploadToR2(imagePath);
console.log(' URL:', imageUrl);
console.log('\n🔍 调用Vision API分析图片...');
try {
const response = await axios.post(`${API_BASE}/chat/index`, {
key: API_KEY,
model: 'gemini-3-pro',
content: VISION_EXTRACT_PROMPT,
image_url: imageUrl
}, {
timeout: 60000
});
const content = response.data.data?.choices?.[0]?.message?.content ||
response.data.data?.content ||
response.data.choices?.[0]?.message?.content;
if (!content) {
console.error('Vision响应为空');
console.log('完整响应:', JSON.stringify(response.data, null, 2));
return null;
}
console.log('\n📝 Vision原始输出:\n');
console.log(content);
// 尝试提取JSON
const jsonMatch = content.match(/\{[\s\S]*\}/);
if (jsonMatch) {
try {
const parsed = JSON.parse(jsonMatch[0]);
console.log('\n✅ 解析后的JSON:\n');
console.log(JSON.stringify(parsed, null, 2));
return parsed;
} catch (e) {
console.log('\n⚠ JSON解析失败但有输出内容');
return { raw: content };
}
}
return { raw: content };
} catch (error) {
console.error('Vision API错误:', error.message);
if (error.response) {
console.error('响应数据:', error.response.data);
}
return null;
}
}
async function main() {
const MATERIAL_DIR = path.join(__dirname, '素材/素材/已有的素材');
const flatImagePath = path.join(MATERIAL_DIR, 'IMG_5683.png');
console.log('='.repeat(60));
console.log('🧪 Vision产品特征提取测试');
console.log('='.repeat(60));
console.log('\n测试图片:', flatImagePath);
const result = await testVisionExtract(flatImagePath);
if (result) {
// 保存结果
const outputPath = path.join(__dirname, 'vision-extract-result.json');
fs.writeFileSync(outputPath, JSON.stringify(result, null, 2));
console.log('\n💾 结果已保存到:', outputPath);
// 如果成功解析生成Golden Description
if (result.overall_description || result.shape) {
console.log('\n' + '='.repeat(60));
console.log('🌟 生成的Golden Product Description:');
console.log('='.repeat(60));
const golden = generateGoldenDescription(result);
console.log(golden);
fs.writeFileSync(
path.join(__dirname, 'golden-description.txt'),
golden
);
}
}
}
function generateGoldenDescription(visionResult) {
if (visionResult.raw) {
return `[需要手动整理Vision输出]\n\n${visionResult.raw}`;
}
const r = visionResult;
return `
EXACT PRODUCT APPEARANCE (AUTO-EXTRACTED BY VISION):
- Shape: ${r.shape?.petal_count || '?'}-PETAL ${r.shape?.type?.toUpperCase() || 'FLOWER'} shape, ${r.shape?.opening || 'C-shaped'} opening
- Color: ${r.color?.name?.toUpperCase() || 'UNKNOWN'} (${r.color?.primary || '#???'})
- Material: ${r.material?.finish || 'Glossy'} ${r.material?.type || 'PU'} fabric with ${r.material?.texture || 'smooth'} texture
- Edge binding: ${r.edge_binding?.color || 'TEAL'} ${r.edge_binding?.material || 'ribbed elastic'} around inner neck hole
- Closure: ${r.closure?.color || 'White'} ${r.closure?.type || 'velcro'} on ${r.closure?.position || 'one petal end'}
- Logo: "${r.logo?.text || 'TOUCHDOG'}" ${r.logo?.style || 'embroidered'} on ${r.logo?.position || 'one petal'}
UNIQUE FEATURES:
${(r.unique_features || []).map(f => `- ${f}`).join('\n') || '- Visible stitching between petals\n- Soft but structured'}
SUMMARY FOR PROMPTS:
${r.overall_description || 'Pet recovery cone with flower-petal design, soft waterproof material.'}
CRITICAL PROHIBITIONS:
- ❌ NO printed patterns or colorful fabric designs
- ❌ NO hard plastic transparent cones
- ❌ NO fully circular/closed shapes (must have C-opening)
- ❌ NO random brand logos or text
`.trim();
}
main().catch(console.error);