import { Injectable } from '@angular/core'; import { FmodeObject, FmodeParse } from 'fmode-ng/parse'; const Parse = FmodeParse.with('nova'); /** * 图片分析结果接口 */ export interface ImageAnalysisResult { // 基础信息 fileName: string; fileSize: number; dimensions: { width: number; height: number; }; // 质量评估 quality: { score: number; // 0-100分 level: 'low' | 'medium' | 'high' | 'ultra'; // 低、中、高、超高 sharpness: number; // 清晰度 0-100 brightness: number; // 亮度 0-100 contrast: number; // 对比度 0-100 detailLevel: 'minimal' | 'basic' | 'detailed' | 'ultra_detailed'; // 🔥 内容精细程度 pixelDensity: 'low' | 'medium' | 'high' | 'ultra_high'; // 🔥 像素密度等级 textureQuality: number; // 🔥 纹理质量 0-100 colorDepth: number; // 🔥 色彩深度 0-100 }; // 内容分析 content: { category: 'white_model' | 'soft_decor' | 'rendering' | 'post_process' | 'unknown'; confidence: number; // 置信度 0-100 description: string; // 内容描述 tags: string[]; // 标签 isArchitectural: boolean; // 是否为建筑相关 hasInterior: boolean; // 是否包含室内场景 hasFurniture: boolean; // 是否包含家具 hasLighting: boolean; // 是否有灯光效果 hasColor?: boolean; // 🔥 是否有色彩(非纯白、非灰度) hasTexture?: boolean; // 🔥 是否有材质纹理 }; // 技术参数 technical: { format: string; // 文件格式 colorSpace: string; // 色彩空间 dpi: number; // 分辨率 aspectRatio: string; // 宽高比 megapixels: number; // 像素数(百万) }; // 建议分类 suggestedStage: 'white_model' | 'soft_decor' | 'rendering' | 'post_process'; suggestedReason: string; // 分类原因 // 设计分析维度(新增) design?: { style: string; // 风格:现代简约、欧式、中式等 atmosphere: string; // 氛围营造方式 material: string; // 材质分析 texture: string; // 纹理特征 quality: string; // 质感描述 form: string; // 形体特征 structure: string; // 空间结构 colorComposition: string; // 色彩组成 }; // 色彩解析报告(新增) colorReport?: { brightness: string; // 明度:低长调/高长调分析 hue: string; // 色相:色彩种类 saturation: string; // 饱和度:低/中/高 openness: string; // 色彩开放度:根据色相种类划分 extractedColors: string[]; // 提取的基础颜色 organizedColors: Array<{ color: string; role: string; percentage: number }>; // 组织颜色(主次) expandedColors: string[]; // 拓展颜色(配色) harmonizedColors: string[]; // 调和颜色(配色) }; // 风格元素分析(新增) styleElements?: { styleKeywords: string[]; // 风格关键词(如:新古典主义、现代轻奢、艺术装饰等) }; // 色彩搭配分析(新增) colorScheme?: { primaryColors: string[]; // 主色调 secondaryColors: string[]; // 辅助色 accentColors: string[]; // 点缀色 }; // 材质分析(新增) materialAnalysis?: { materials: string[]; // 识别的材质(大理石、玻璃、布、金属等) }; // 布局特征分析(新增) layoutFeatures?: { features: string[]; // 布局特征(对称式布局、多区域采光、开放式空间等) }; // 空间氛围分析(新增) atmosphereAnalysis?: { atmosphere: string; // 空间氛围描述 }; // AI分析时间 analysisTime: number; // 分析耗时(毫秒) analysisDate: string; // 分析时间 } /** * 图片分析服务 * 基于豆包1.6模型进行图片内容识别和质量评估 */ @Injectable({ providedIn: 'root' }) export class ImageAnalysisService { // 使用豆包1.6模型 private readonly MODEL = 'fmode-1.6-cn'; constructor() {} /** * 动态加载 completionJSON,避免编译路径不兼容 */ private async callCompletionJSON( prompt: string, outputSchema: string, onStream?: (content: any) => void, retry: number = 2, options: any = {} ): Promise { const mod = await import('fmode-ng/core/agent/chat/completion'); const completionJSON = (mod as any).completionJSON as ( prompt: string, output: string, onStream?: (content: any) => void, retry?: number, options?: any ) => Promise; return completionJSON(prompt, outputSchema, onStream, retry, options); } /** * 分析单张图片 */ async analyzeImage( imageUrl: string, file: File, onProgress?: (progress: string) => void ): Promise { const startTime = Date.now(); try { onProgress?.('正在分析图片内容...'); // 获取图片基础信息 const basicInfo = await this.getImageBasicInfo(file); onProgress?.('正在进行AI内容识别...'); // 使用豆包1.6进行内容分析 const contentAnalysis = await this.analyzeImageContent(imageUrl); onProgress?.('正在评估图片质量...'); // 质量评估 const qualityAnalysis = await this.analyzeImageQuality(imageUrl, basicInfo); onProgress?.('正在生成分析报告...'); // 综合分析结果 const result: ImageAnalysisResult = { fileName: file.name, fileSize: file.size, dimensions: basicInfo.dimensions, quality: qualityAnalysis, content: contentAnalysis, technical: { format: file.type, colorSpace: 'sRGB', // 默认值,实际可通过更深入分析获得 dpi: basicInfo.dpi || 72, aspectRatio: this.calculateAspectRatio(basicInfo.dimensions.width, basicInfo.dimensions.height), megapixels: Math.round((basicInfo.dimensions.width * basicInfo.dimensions.height) / 1000000 * 100) / 100 }, suggestedStage: this.determineSuggestedStage(contentAnalysis, qualityAnalysis), suggestedReason: this.generateSuggestionReason(contentAnalysis, qualityAnalysis), analysisTime: Date.now() - startTime, analysisDate: new Date().toISOString() }; onProgress?.('分析完成'); return result; } catch (error) { console.error('图片分析失败:', error); throw new Error('图片分析失败: ' + (error as Error).message); } } /** * 获取图片基础信息 */ private async getImageBasicInfo(file: File): Promise<{ dimensions: { width: number; height: number }; dpi?: number; }> { return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => { resolve({ dimensions: { width: img.naturalWidth, height: img.naturalHeight }, dpi: 72 // 默认DPI,实际项目中可以通过EXIF数据获取 }); }; img.onerror = () => reject(new Error('无法加载图片')); img.src = URL.createObjectURL(file); }); } /** * 使用豆包1.6分析图片内容 */ private async analyzeImageContent(imageUrl: string): Promise { const prompt = `请分析这张室内设计相关的图片,并按以下JSON格式输出分析结果: { "category": "图片类别(white_model/soft_decor/rendering/post_process/unknown)", "confidence": "置信度(0-100)", "description": "详细的内容描述", "tags": ["标签1", "标签2", "标签3"], "isArchitectural": "是否为建筑相关(true/false)", "hasInterior": "是否包含室内场景(true/false)", "hasFurniture": "是否包含家具(true/false)", "hasLighting": "是否有灯光效果(true/false)", "hasColor": "是否有色彩(非纯白、非灰度)(true/false)", "hasTexture": "是否有材质纹理(true/false)" } 分类标准: - white_model: 白模、线框图、基础建模、结构图(特征:纯白色或灰色、无色彩、无材质、无家具、无灯光) - soft_decor: 软装搭配、家具配置、装饰品、材质贴图(特征:有家具、有色彩、有材质、但灯光不突出) - rendering: 渲染图、效果图、光影表现、材质细节(特征:有灯光效果、有色彩、有材质、质量较高) - post_process: 后期处理、色彩调整、特效、最终成品(特征:完整场景、精致色彩、专业质量) 重要判断依据: 1. 如果图片是纯白色或灰色草图,无任何色彩 → 白模 2. 如果图片有丰富色彩和材质 → 不是白模 3. 如果图片有灯光效果 → 渲染或后期 4. 如果图片有家具但无灯光 → 软装 要求: 1. 准确识别图片中的设计元素 2. 特别注意图片是否有色彩(区分白模和渲染图的关键) 3. 判断图片的制作阶段和用途 4. 提取关键的视觉特征`; const output = `{ "category": "white_model", "confidence": 85, "description": "室内空间白模图,显示了基础的空间结构", "tags": ["白模", "室内", "结构"], "isArchitectural": true, "hasInterior": true, "hasFurniture": false, "hasLighting": false, "hasColor": false, "hasTexture": false }`; try { const result = await this.callCompletionJSON( prompt, output, (content) => { console.log('AI分析进度:', content?.length || 0); }, 2, { model: this.MODEL, vision: true, images: [imageUrl] } ); return result || { category: 'unknown', confidence: 0, description: '无法识别图片内容', tags: [], isArchitectural: false, hasInterior: false, hasFurniture: false, hasLighting: false }; } catch (error) { console.error('内容分析失败:', error); return { category: 'unknown', confidence: 0, description: '内容分析失败', tags: [], isArchitectural: false, hasInterior: false, hasFurniture: false, hasLighting: false }; } } /** * 🔥 分析图片质量(增强版:包含精细度和像素密度) */ private async analyzeImageQuality( imageUrl: string, basicInfo: { dimensions: { width: number; height: number } } ): Promise { const prompt = `请分析这张室内设计图片的质量,并按以下JSON格式输出: { "score": "总体质量分数(0-100)", "level": "质量等级(low/medium/high/ultra)", "sharpness": "清晰度(0-100)", "brightness": "亮度(0-100)", "contrast": "对比度(0-100)", "textureQuality": "纹理质量(0-100)", "colorDepth": "色彩深度(0-100)" } 评估标准: - score: 综合质量评分,考虑清晰度、构图、色彩、纹理等 - level: low(<60分), medium(60-75分), high(75-90分), ultra(>90分) - sharpness: 图片清晰度,是否有模糊、噪点、锯齿 - brightness: 亮度是否适中,不过暗或过亮 - contrast: 对比度是否合适,层次是否分明 - textureQuality: 纹理质量,材质细节是否清晰(木纹、布纹、石材等) - colorDepth: 色彩深度,色彩过渡是否自然,是否有色带 请客观评估图片质量,重点关注专业室内设计图片的标准。`; const output = `{ "score": 75, "level": "high", "sharpness": 80, "brightness": 70, "contrast": 75, "textureQuality": 75, "colorDepth": 80 }`; try { const result = await this.callCompletionJSON( prompt, output, (content) => { console.log('🔍 质量分析进度:', content?.length || 0); }, 2, { model: this.MODEL, vision: true, images: [imageUrl] } ); // 🔥 结合图片分辨率和像素密度进行质量调整 const resolutionScore = this.calculateResolutionScore(basicInfo.dimensions); const pixelDensity = this.calculatePixelDensity(basicInfo.dimensions); // 🔥 评估内容精细程度 const detailLevel = await this.evaluateDetailLevel(imageUrl, basicInfo.dimensions); // 🔥 综合评分:AI评分(40%) + 分辨率(30%) + 纹理质量(20%) + 色彩深度(10%) const adjustedScore = Math.round( result.score * 0.4 + resolutionScore * 0.3 + (result.textureQuality || 50) * 0.2 + (result.colorDepth || 50) * 0.1 ); console.log('📊 质量分析结果:', { AI评分: result.score, 分辨率评分: resolutionScore, 纹理质量: result.textureQuality, 色彩深度: result.colorDepth, 综合评分: adjustedScore, 像素密度: pixelDensity, 精细程度: detailLevel }); return { score: adjustedScore, level: this.getQualityLevel(adjustedScore), sharpness: result.sharpness || 50, brightness: result.brightness || 50, contrast: result.contrast || 50, detailLevel: detailLevel, pixelDensity: pixelDensity, textureQuality: result.textureQuality || 50, colorDepth: result.colorDepth || 50 }; } catch (error) { console.error('❌ 质量分析失败:', error); // 基于分辨率和像素的备选评估 const resolutionScore = this.calculateResolutionScore(basicInfo.dimensions); const pixelDensity = this.calculatePixelDensity(basicInfo.dimensions); const megapixels = (basicInfo.dimensions.width * basicInfo.dimensions.height) / 1000000; // 根据像素推测精细程度 let detailLevel: 'minimal' | 'basic' | 'detailed' | 'ultra_detailed' = 'basic'; if (megapixels >= 8) detailLevel = 'ultra_detailed'; else if (megapixels >= 2) detailLevel = 'detailed'; else if (megapixels >= 0.9) detailLevel = 'basic'; else detailLevel = 'minimal'; return { score: resolutionScore, level: this.getQualityLevel(resolutionScore), sharpness: 50, brightness: 50, contrast: 50, detailLevel: detailLevel, pixelDensity: pixelDensity, textureQuality: resolutionScore * 0.8, colorDepth: resolutionScore * 0.9 }; } } /** * 🔥 基于分辨率和像素密度计算质量分数(更精细) */ private calculateResolutionScore(dimensions: { width: number; height: number }): number { const totalPixels = dimensions.width * dimensions.height; const megapixels = totalPixels / 1000000; // 更精细的像素分级 if (megapixels >= 33) return 98; // 8K (7680×4320) if (megapixels >= 24) return 96; // 6K (6144×3160) if (megapixels >= 16) return 94; // 5K (5120×2880) if (megapixels >= 8) return 92; // 4K (3840×2160) if (megapixels >= 6) return 88; // 2.5K+ (2560×2304) if (megapixels >= 4) return 84; // QHD+ (2560×1600) if (megapixels >= 2) return 78; // 1080p (1920×1080) if (megapixels >= 1) return 68; // 720p+ (1280×720) if (megapixels >= 0.5) return 55; // 中等分辨率 if (megapixels >= 0.3) return 40; // 低分辨率 return 25; // 极低分辨率 } /** * 🔥 计算像素密度等级 */ private calculatePixelDensity(dimensions: { width: number; height: number }): 'low' | 'medium' | 'high' | 'ultra_high' { const totalPixels = dimensions.width * dimensions.height; const megapixels = totalPixels / 1000000; if (megapixels >= 8) return 'ultra_high'; // 4K及以上 if (megapixels >= 2) return 'high'; // 1080p及以上 if (megapixels >= 0.9) return 'medium'; // 720p及以上 return 'low'; // 低于720p } /** * 🔥 评估内容精细程度 */ private async evaluateDetailLevel( imageUrl: string, dimensions: { width: number; height: number } ): Promise<'minimal' | 'basic' | 'detailed' | 'ultra_detailed'> { const prompt = `请评估这张室内设计图片的内容精细程度,并返回JSON: { "detailLevel": "精细程度(minimal/basic/detailed/ultra_detailed)", "textureQuality": "纹理质量评分(0-100)", "colorDepth": "色彩深度评分(0-100)", "reasoning": "评估理由" } 评估标准: - minimal: 极简图,只有基本轮廓,无细节纹理 - basic: 基础图,有简单纹理和色彩,细节较少 - detailed: 详细图,有丰富纹理、材质细节、光影效果 - ultra_detailed: 超精细图,有极致纹理、真实材质、复杂光影、细微细节 重点关注: 1. 纹理细节(木纹、布纹、石材纹理等) 2. 材质表现(金属反射、玻璃透明度、布料质感等) 3. 光影效果(阴影、高光、环境光等) 4. 细微元素(装饰品细节、边角处理等)`; const output = `{ "detailLevel": "detailed", "textureQuality": 75, "colorDepth": 80, "reasoning": "图片包含丰富的纹理和材质细节" }`; try { const result = await this.callCompletionJSON( prompt, output, undefined, 2, { model: this.MODEL, vision: true, images: [imageUrl] } ); return result.detailLevel || 'basic'; } catch (error) { console.error('精细程度评估失败:', error); // 基于分辨率的备选评估 const megapixels = (dimensions.width * dimensions.height) / 1000000; if (megapixels >= 8) return 'ultra_detailed'; if (megapixels >= 2) return 'detailed'; if (megapixels >= 0.9) return 'basic'; return 'minimal'; } } /** * 获取质量等级 */ private getQualityLevel(score: number): 'low' | 'medium' | 'high' | 'ultra' { if (score >= 90) return 'ultra'; if (score >= 75) return 'high'; if (score >= 60) return 'medium'; return 'low'; } /** * 计算宽高比 */ private calculateAspectRatio(width: number, height: number): string { const gcd = (a: number, b: number): number => b === 0 ? a : gcd(b, a % b); const divisor = gcd(width, height); return `${width / divisor}:${height / divisor}`; } /** * 🔥 确定建议的阶段分类(优化版:更精准的判断逻辑) */ private determineSuggestedStage( content: ImageAnalysisResult['content'], quality: ImageAnalysisResult['quality'] ): 'white_model' | 'soft_decor' | 'rendering' | 'post_process' { // 如果AI已经识别出明确类别且置信度高 if (content.confidence > 75 && content.category !== 'unknown') { return content.category as any; } // 🔥 综合判断:像素密度 + 内容精细度 + 质量分数 + 特征 const megapixels = quality.pixelDensity; const detailLevel = quality.detailLevel; const qualityScore = quality.score; const textureQuality = quality.textureQuality; console.log('🎯 阶段判断依据:', { 像素密度: megapixels, 精细程度: detailLevel, 质量分数: qualityScore, 纹理质量: textureQuality, 有家具: content.hasFurniture, 有灯光: content.hasLighting, 有色彩: content.hasColor, 有纹理: content.hasTexture }); // 🔥 白模阶段:放宽条件,更准确识别白色/灰色无渲染的图片 // 修复:默认值应该是false(无色彩/无纹理),而不是true const hasColor = content.hasColor === true; // 🔥 修复:只有明确有色彩才为true const hasTexture = content.hasTexture === true; // 🔥 修复:只有明确有纹理才为true // 🔥 白模判断:无装饰 + 无灯光 + 低质量 (放宽色彩和纹理条件) if (!content.hasFurniture && !content.hasLighting && qualityScore < 65 && // 🔥 放宽质量要求(原60提升到65) !hasColor) { // 🔥 主要看是否有色彩,纹理可以忽略 console.log('✅ 判定为白模阶段:无装饰 + 无灯光 + 无色彩 + 低质量'); return 'white_model'; } // 🔥 如果质量极低且无装饰,也判定为白模 if (qualityScore < 50 && !content.hasFurniture && !content.hasLighting) { console.log('✅ 判定为白模阶段:极低质量 + 无装饰'); return 'white_model'; } // 🔥 如果有明显色彩或灯光,绝对不是白模 if (hasColor || content.hasLighting) { console.log('✅ 有色彩或灯光,不是白模,继续判断其他阶段'); } // 🔥 软装阶段:有家具 + 无灯光 + 中等质量 if (content.hasFurniture && !content.hasLighting && qualityScore >= 60 && qualityScore < 80) { console.log('✅ 判定为软装阶段:有家具 + 无灯光'); return 'soft_decor'; } // 🔥 渲染阶段:有灯光 + 高质量 + 详细精细度 if (content.hasLighting && (detailLevel === 'detailed' || detailLevel === 'ultra_detailed') && qualityScore >= 75 && qualityScore < 90) { console.log('✅ 判定为渲染阶段:有灯光 + 高质量 + 详细精细度'); return 'rendering'; } // 🔥 后期处理阶段:超高质量 + 超精细 + 高纹理质量 if (qualityScore >= 90 && detailLevel === 'ultra_detailed' && textureQuality >= 85 && (megapixels === 'ultra_high' || megapixels === 'high')) { console.log('✅ 判定为后期处理阶段:超高质量 + 超精细'); return 'post_process'; } // 🔥 渲染阶段:有灯光效果,即使质量不是最高 if (content.hasLighting && qualityScore >= 70) { console.log('✅ 判定为渲染阶段:有灯光效果'); return 'rendering'; } // 🔥 软装阶段:有家具但质量一般 if (content.hasFurniture && qualityScore >= 60) { console.log('✅ 判定为软装阶段:有家具'); return 'soft_decor'; } // 🔥 默认:根据质量分数判断(优先渲染,避免误判为白模) if (qualityScore >= 85) { console.log('✅ 默认判定为后期处理阶段:高质量'); return 'post_process'; } else if (qualityScore >= 65) { console.log('✅ 默认判定为渲染阶段:中高质量'); return 'rendering'; } else if (qualityScore >= 50) { console.log('✅ 默认判定为软装阶段:中等质量'); return 'soft_decor'; } else if (qualityScore >= 40) { console.log('✅ 默认判定为渲染阶段:低质量但有内容'); return 'rendering'; // 🔥 即使质量低,也优先判定为渲染而非白模 } else { console.log('⚠️ 默认判定为白模阶段:极低质量'); return 'white_model'; } } /** * 生成分类建议原因 */ private generateSuggestionReason( content: ImageAnalysisResult['content'], quality: ImageAnalysisResult['quality'] ): string { const reasons = []; if (content.confidence > 70) { reasons.push(`AI识别置信度${content.confidence}%`); } if (quality.score >= 90) { reasons.push('图片质量极高,适合最终展示'); } else if (quality.score >= 75) { reasons.push('图片质量良好'); } else if (quality.score < 60) { reasons.push('图片质量较低,可能为初期阶段'); } if (content.hasLighting) { reasons.push('包含灯光效果'); } if (content.hasFurniture) { reasons.push('包含家具配置'); } if (!content.hasFurniture && !content.hasLighting) { reasons.push('基础结构图,无装饰元素'); } return reasons.join(',') || '基于图片特征综合判断'; } /** * 批量分析图片 */ async analyzeImages( files: { file: File; url: string }[], onProgress?: (current: number, total: number, currentFileName: string) => void ): Promise { const results: ImageAnalysisResult[] = []; for (let i = 0; i < files.length; i++) { const { file, url } = files[i]; onProgress?.(i + 1, files.length, file.name); try { const result = await this.analyzeImage(url, file); results.push(result); } catch (error) { console.error(`分析文件 ${file.name} 失败:`, error); // 创建一个基础的错误结果 results.push(this.createErrorResult(file, error as Error)); } } return results; } /** * 创建错误结果 */ private createErrorResult(file: File, error: Error): ImageAnalysisResult { return { fileName: file.name, fileSize: file.size, dimensions: { width: 0, height: 0 }, quality: { score: 0, level: 'low', sharpness: 0, brightness: 0, contrast: 0, detailLevel: 'minimal', pixelDensity: 'low', textureQuality: 0, colorDepth: 0 }, content: { category: 'unknown', confidence: 0, description: `分析失败: ${error.message}`, tags: [], isArchitectural: false, hasInterior: false, hasFurniture: false, hasLighting: false }, technical: { format: file.type, colorSpace: 'unknown', dpi: 0, aspectRatio: '0:0', megapixels: 0 }, suggestedStage: 'white_model', suggestedReason: '分析失败,默认分类', analysisTime: 0, analysisDate: new Date().toISOString() }; } /** * 保存分析结果到数据库 */ async saveAnalysisResult( projectId: string, spaceId: string, stageType: string, analysisResult: ImageAnalysisResult ): Promise { try { // 查询项目 const projectQuery = new Parse.Query('Project'); const project = await projectQuery.get(projectId); if (!project) { throw new Error('项目不存在'); } // 获取现有的date数据 const dateData = project.get('date') || {}; // 初始化图片分析数据结构 if (!dateData.imageAnalysis) { dateData.imageAnalysis = {}; } if (!dateData.imageAnalysis[spaceId]) { dateData.imageAnalysis[spaceId] = {}; } if (!dateData.imageAnalysis[spaceId][stageType]) { dateData.imageAnalysis[spaceId][stageType] = []; } // 添加分析结果 dateData.imageAnalysis[spaceId][stageType].push(analysisResult); // 保存到项目 project.set('date', dateData); await project.save(); console.log('图片分析结果已保存到项目数据库'); } catch (error) { console.error('保存分析结果失败:', error); throw error; } } /** * 🔥 快速生成模拟分析结果(用于开发测试) * 根据文件名和空间名称快速生成分析结果,无需调用AI */ generateMockAnalysisResult( file: File, spaceName?: string, stageName?: string ): ImageAnalysisResult { const fileName = file.name.toLowerCase(); const fileSize = file.size; let suggestedStage: 'white_model' | 'soft_decor' | 'rendering' | 'post_process' = 'white_model'; let category: 'white_model' | 'soft_decor' | 'rendering' | 'post_process' | 'unknown' = 'white_model'; let confidence = 75; let analysisReason = '基于文件名和特征分析'; // 增强的关键词匹配 const stageKeywords = { white_model: ['白模', 'white', 'model', '毛坯', '空间', '结构', '框架', '基础'], soft_decor: ['软装', 'soft', 'decor', '家具', 'furniture', '装饰', '饰品', '布艺'], rendering: ['渲染', 'render', '效果', 'effect', '光照', '材质', '质感'], post_process: ['后期', 'post', 'final', '最终', '完成', '成品', '精修', '调色'] }; // 分析文件名匹配度 let maxMatchScore = 0; let bestStage = 'white_model'; Object.entries(stageKeywords).forEach(([stage, keywords]) => { const matchScore = keywords.reduce((score, keyword) => { if (fileName.includes(keyword)) { return score + (keyword.length > 2 ? 2 : 1); // 长关键词权重更高 } return score; }, 0); if (matchScore > maxMatchScore) { maxMatchScore = matchScore; bestStage = stage as typeof suggestedStage; } }); if (maxMatchScore > 0) { suggestedStage = bestStage as 'white_model' | 'soft_decor' | 'rendering' | 'post_process'; category = bestStage as 'white_model' | 'soft_decor' | 'rendering' | 'post_process'; confidence = Math.min(75 + maxMatchScore * 5, 95); analysisReason = `文件名包含${this.getStageName(bestStage)}相关关键词`; } // 文件大小分析 if (fileSize > 8 * 1024 * 1024) { // 大于8MB if (suggestedStage === 'white_model') { suggestedStage = 'rendering'; category = 'rendering'; confidence = Math.min(confidence + 10, 95); analysisReason += ',大文件更可能是高质量渲染图'; } } else if (fileSize < 500 * 1024) { // 小于500KB if (suggestedStage === 'post_process') { suggestedStage = 'white_model'; category = 'white_model'; confidence = Math.max(confidence - 10, 60); analysisReason += ',小文件更可能是简单的白模图'; } } // 根据目标阶段调整 if (stageName) { const targetStageMap: Record = { '白模': 'white_model', '软装': 'soft_decor', '渲染': 'rendering', '后期': 'post_process' }; const targetStage = targetStageMap[stageName]; if (targetStage && targetStage === suggestedStage) { confidence = Math.min(confidence + 15, 98); analysisReason += `,与目标阶段一致`; } } const qualityScoreMap = { 'white_model': 75, 'soft_decor': 82, 'rendering': 88, 'post_process': 95 }; const score = qualityScoreMap[suggestedStage]; // 生成模拟分析结果 const result: ImageAnalysisResult = { fileName: file.name, fileSize: file.size, dimensions: { width: 1920 + Math.floor(Math.random() * 400), // 模拟不同尺寸 height: 1080 + Math.floor(Math.random() * 300) }, quality: { score: score, level: this.getQualityLevel(score), sharpness: Math.min(score + Math.floor(Math.random() * 10), 100), brightness: Math.max(score - Math.floor(Math.random() * 10), 50), contrast: Math.min(score + Math.floor(Math.random() * 8), 100), detailLevel: score >= 90 ? 'ultra_detailed' : score >= 75 ? 'detailed' : score >= 60 ? 'basic' : 'minimal', pixelDensity: score >= 90 ? 'ultra_high' : score >= 75 ? 'high' : score >= 60 ? 'medium' : 'low', textureQuality: Math.min(score + Math.floor(Math.random() * 5), 100), colorDepth: Math.min(score + Math.floor(Math.random() * 5), 100) }, content: { category: category, confidence: confidence, description: `${spaceName || '室内空间'}${this.getStageName(suggestedStage)}图`, tags: this.generateTags(suggestedStage, spaceName), isArchitectural: true, hasInterior: true, hasFurniture: suggestedStage !== 'white_model', hasLighting: suggestedStage === 'rendering' || suggestedStage === 'post_process' }, technical: { format: file.type, colorSpace: Math.random() > 0.8 ? 'Adobe RGB' : 'sRGB', dpi: Math.random() > 0.5 ? 300 : 72, aspectRatio: this.calculateAspectRatio(1920, 1080), megapixels: Math.round(((1920 * 1080) / 1000000) * 100) / 100 }, suggestedStage: suggestedStage, suggestedReason: analysisReason, analysisTime: 50 + Math.floor(Math.random() * 100), analysisDate: new Date().toISOString() }; console.log(`🚀 增强模拟分析结果: ${file.name} -> ${this.getStageName(suggestedStage)}`, { confidence: confidence, reason: analysisReason, fileSize: `${(fileSize / 1024 / 1024).toFixed(1)}MB` }); return result; } /** * 生成标签 */ private generateTags(stage: string, spaceName?: string): string[] { const baseTags = [this.getStageName(stage), spaceName || '室内', '设计']; const stageSpecificTags: Record = { 'white_model': ['建筑', '结构', '空间布局'], 'soft_decor': ['家具', '装饰', '色彩搭配'], 'rendering': ['渲染', '光影', '材质'], 'post_process': ['后期', '色彩调整', '成品'] }; return [...baseTags, ...(stageSpecificTags[stage] || [])]; } /** * 获取阶段名称 */ private getStageName(stageType: string): string { const stageMap: { [key: string]: string } = { 'white_model': '白模', 'soft_decor': '软装', 'rendering': '渲染', 'post_process': '后期' }; return stageMap[stageType] || stageType; } }