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 spaceType?: string; // 🔥 空间类型(客厅/卧室/餐厅/厨房/卫生间/书房) 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; // 空间氛围描述 }; // 🔥 渲染专业分析(新增 - 基于行业标准) renderingAnalysis?: { // 一、像素大小与清晰度维度 pixelClarityDimension: { pixelLevel: 'preview' | 'standard' | 'high' | 'ultra' | 'print'; // 像素级别 estimatedSize: { width: number; // 估算宽度 height: number; // 估算高度 description: string; // 尺寸描述 }; detailRetention: { structureClarity: string; // 基础结构清晰度(沙发轮廓、柜体线条) textureClarity: string; // 精细纹理清晰度(藤编、木纹、金属拉丝) edgeSharpness: string; // 边缘锐度 blurIssue: boolean; // 是否存在模糊 blurDescription?: string; // 模糊描述 }; scaleLoss: { pixelBlockEffect: boolean; // 是否有像素块感 highFrequencyLoss: string; // 高频细节损耗评价 enlargeSuitability: string; // 放大适用性 }; optimizationSuggestions: string[]; // 像素优化建议 }; // 二、色彩精细程度维度 colorRefinementDimension: { colorStyle: string; // 色彩风格(自然低饱和系、高饱和系等) refinementLevel: 'basic' | 'intermediate' | 'advanced' | 'professional'; // 精细度等级 colorGamutCoverage: { dominantColors: string[]; // 主导色彩 colorSpace: 'sRGB' | 'Adobe RGB' | 'ProPhoto RGB'; // 色彩空间 saturationRange: string; // 饱和度范围 colorDescription: string; // 色域描述 }; colorAccuracy: { materialColors: Array<{ material: string; // 材质名称(木质、沙发面料等) colorDescription: string; // 色彩描述 deltaE: number; // 色差值ΔE(参考CQS标准) }>; differentiationAbility: string; // 材质色彩区分能力 gradientTransition: { smoothness: string; // 同色系层次过渡(如墙面阴影灰度变化) gradeLevels: number; // 过渡级数 }; }; colorConsistency: { crossImageConsistency: boolean; // 跨图片色彩一致性 metallicGlassReflection: string; // 金属、玻璃反光色彩评价 environmentColorBlend: boolean; // 环境色融合 environmentColorDescription?: string; // 环境色融合描述 }; optimizationSuggestions: string[]; // 色彩优化建议 }; // 三、灯光氛围维度 lightingAtmosphereDimension: { lightingStyle: string; // 灯光风格(柔和自然系、戏剧化、工业风等) atmosphereLevel: 'basic' | 'good' | 'excellent' | 'master'; // 氛围营造等级 lightSources: { primary: Array<{ type: string; // 光源类型(窗外漫射自然光等) position: string; // 位置 characteristics: string; // 特征 }>; auxiliary: Array<{ type: string; // 辅助光源类型(吊顶灯带、壁灯等) coverage: string; // 覆盖范围 effectiveness: string; // 效果评价 }>; }; lightShadowHierarchy: { contrastRatio: string; // 明暗对比度(如1:4) shadowTransition: string; // 阴影过渡自然度 keyIssues: string[]; // 核心问题(如光源指向性弱) highlightQuality: { definition: string; // 高光区域清晰度 spotShape: string; // 光斑形态 hardLightAccent: boolean; // 是否有硬光点缀 hardLightDescription?: string; // 硬光描述 }; spatialDepth: string; // 空间立体感 }; atmosphereAdaptation: { colorTemperature: string; // 色温(如4000K暖白光) spacePositioning: string; // 空间定位适配(简约舒适等) decorativeLightOutput: { wallLampHalo: string; // 壁灯光晕范围 floorLampEffect: string; // 落地灯效果 localSoftLightZone: boolean; // 是否形成局部柔和光区 }; }; optimizationSuggestions: string[]; // 灯光优化建议 }; // 综合评分和建议 overallScore: number; // 渲染综合评分 0-100 renderingQualityLevel: 'preview' | 'standard' | 'professional' | 'master'; // 渲染质量等级 strengths: string[]; // 优点 improvements: string[]; // 改进建议 optimizationPrompts?: { pixelOptimization?: string; // 像素优化提示词 colorOptimization?: string; // 色彩优化提示词 lightingOptimization?: string; // 灯光优化提示词 }; }; // 🔥 后期处理专业分析(新增 - 基于行业标准,与渲染阶段对比) postProcessAnalysis?: { // 一、像素与清晰度维度(对比渲染小图) pixelClarityComparison: { beforeRendering: { pixelRange: string; // 前期像素范围(如800-1200像素宽) clarityLevel: string; // 清晰度级别(预览级) textureIssues: string[]; // 纹理问题(如藤编模糊、木纹不清) edgeIssues: string[]; // 边缘问题(如锐度不足、像素块感) }; afterPostProcess: { pixelRange: string; // 后期像素范围(如2000+像素宽) clarityLevel: string; // 清晰度级别(成品级) textureQuality: { details: string[]; // 材质细节(藤编肌理、木纹结疤、金属拉丝等) clarity: string; // 清晰度描述 }; edgeQuality: string; // 边缘质量(锐利、无像素损耗) printSuitability: boolean; // 是否满足印刷/展示需求 }; qualityLeap: string; // 质变描述(从预览级到成品级) }; // 二、色彩精细度维度(对比渲染小图) colorRefinementComparison: { beforeRendering: { gradientLevels: number; // 同色系过渡级数(如3级) deltaE: number; // 材质色差值ΔE(如3-5) colorLayers: string; // 色彩层次描述(单一) }; afterPostProcess: { gradientLevels: number; // 同色系过渡级数(如5-8级) deltaE: number; // 材质色差值ΔE(如≤2) gradientDetails: string[]; // 渐变细节(如墙面亮白到阴影灰) materialColorAccuracy: Array<{ material: string; // 材质名称 improvement: string; // 改进描述 }>; environmentColorBlend: { enabled: boolean; // 是否融合环境色 examples: string[]; // 融合示例(如金属腿反射木色光晕) }; microColorDetails: string[]; // 微色彩细节(藤编浅黄、陶罐土棕等) }; qualityLeap: string; // 质变描述(从中阶写实到高还原质感) }; // 三、灯光氛围维度(对比渲染小图) lightingAtmosphereComparison: { beforeRendering: { issues: string[]; // 问题(光源指向性弱、高光光斑模糊、空间立体感不足) atmosphereLevel: string; // 氛围等级 }; afterPostProcess: { lightSourceHierarchy: { primaryLight: { type: string; // 主光源类型(窗外自然光) diffuseLight: string; // 漫射光描述 directLight: { percentage: number; // 直射光比例(如15%) spotAreas: string[]; // 光斑区域(沙发扶手、桌面等) }; }; auxiliaryLight: { sources: Array<{ type: string; // 辅助光源类型(吊顶灯带、壁灯) haloExpansion: string; // 光晕扩大范围(如壁灯覆盖墙面30cm) }>; }; }; shadowQualityUpgrade: { softTransition: boolean; // 保留柔和过渡 microHardEdge: { enabled: boolean; // 是否新增微硬边阴影 areas: string[]; // 微硬边区域(柜体底部、物品边缘) }; spatialDepthEnhancement: string; // 空间纵深感强化 }; atmosphereDetails: { environmentReflection: { enabled: boolean; // 是否新增环境光反射 examples: string[]; // 反射示例(地面反射家具轮廓、墙面反射灯光暖调) }; naturalness: string; // 自然度描述 }; }; qualityLeap: string; // 质变描述(从柔和但平到层次化氛围) }; // 四、后期新增细节维度 postProcessDetailsAddition: { beforeRendering: { detailLevel: string; // 细节级别(基础结构) itemClarity: string; // 物品清晰度(如茶几物品模糊) }; afterPostProcess: { lifeDetails: Array<{ item: string; // 物品名称(玻璃杯、书籍、陶罐、植物等) description: string; // 细节描述(封面纹理、枝叶细节等) }>; livingAtmosphere: string; // 真实居住感描述 detailEnhancement: string; // 细节增强总结 }; qualityLeap: string; // 质变描述(从基础结构到生活感填充) }; // 综合评分和建议 overallScore: number; // 后期处理综合评分 0-100 postProcessQualityLevel: 'good' | 'excellent' | 'master' | 'exceptional'; // 后期处理质量等级 strengths: string[]; // 优点 comparisonSummary: string; // 与渲染阶段对比总结 }; // 🔥 软装专业分析(新增 - 基于行业标准) softDecorAnalysis?: { // 一、材质维度 materialDimension: { materialTypes: Array<{ name: string; // 材质名称(水泥、实木、藤编、皮革、大理石等) proportion: number; // 占比百分比 area: string; // 使用区域 }>; materialBalance: string; // 材质占比均衡性评价 textureContrast: { hardMaterials: string[]; // 硬材质列表 softMaterials: string[]; // 软材质列表 contrastEffect: string; // 冷暖/刚柔对比效果 }; textureDetails: { clarity: string; // 肌理清晰度评价 homogenization: boolean; // 是否存在材质同质化问题 description: string; // 肌理细节描述 }; materialEcho: string; // 不同区域材质呼应关系 }; // 二、灯光维度 lightingDimension: { lightSources: { natural: string[]; // 自然光源(窗户位置) artificial: string[]; // 人工光源(吊灯、壁灯、筒灯等) distribution: string; // 光源分布评价 hierarchy: string; // 主光源、辅助光层次评价 }; colorTemperature: { temperature: string; // 色温类型(暖白光、冷白光等) materialMatch: string; // 与软装材质的匹配度 conflict: boolean; // 是否存在色温冲突 conflictDescription?: string; // 冲突描述 }; lightShadow: { focusPoints: string[]; // 灯光突出的软装重点 contrastNaturalness: string; // 明暗对比自然度(暗部有细节、亮部不曝) shadowQuality: string; // 阴影质量评价 }; atmosphereMatch: string; // 灯光氛围与空间功能契合度 }; // 三、颜色维度 colorDimension: { colorHierarchy: { primary: Array<{ color: string; proportion: number }>; // 主色调及占比 secondary: Array<{ color: string; proportion: number }>; // 辅助色及占比 accent: Array<{ color: string; proportion: number }>; // 点缀色及占比 ratio631: boolean; // 是否符合6:3:1原则 ratio631Analysis: string; // 6:3:1原则分析 }; colorTone: { overallTone: string; // 整体色调(低饱和、暖调等) consistency: boolean; // 色调是否统一 jumpingIssue: boolean; // 是否存在跳脱感 jumpingDescription?: string; // 跳脱感描述 }; colorMaterialRelation: string; // 色彩如何强化材质质感 colorBalance: { warmColors: string[]; // 暖色列表 coolColors: string[]; // 冷色列表 balance: string; // 冷暖平衡评价 imbalanceIssue: boolean; // 是否存在冷暖失衡 }; }; // 四、像素维度 pixelDimension: { pixelSize: { width: number; height: number; meets2K: boolean; // 是否≥1920×1080px detailClarity: string; // 放大后细节清晰度 }; imageQuality: { format: string; // 图片格式 isLossless: boolean; // 是否无损格式 compressionIssue: boolean; // 是否有压缩导致的模糊/噪点 qualityDescription: string; // 画质描述 }; resolution: { dpi: number; meetsScreen: boolean; // 是否≥72dpi(屏幕展示) meetsPrint: boolean; // 是否≥300dpi(打印) }; detailPresentation: string; // 微小元素细节呈现评价 }; // 五、整体适配性 overallAdaptability: { styleConsistency: { style: string; // 软装风格 consistency: boolean; // 风格是否统一 fragmentation: boolean; // 是否存在风格割裂 fragmentationDescription?: string; // 割裂描述 }; proportionMatch: { furnitureSizes: Array<{ name: string; size: string; suitability: string }>; // 家具尺寸适配性 spaceCoordination: string; // 与空间层高/面积协调度 sizeIssue: boolean; // 是否存在过大/过小问题 sizeIssueDescription?: string; // 尺寸问题描述 }; functionAesthetics: { practicalExamples: string[]; // 实用性举例(储物、动线等) decorativeExamples: string[]; // 装饰性举例 balanceMethod: string; // 功能与美学平衡方式 }; atmosphereConsistency: { emotionalTone: string; // 情感基调(松弛、质朴等) consistency: boolean; // 是否在所有区域统一 inconsistencyDescription?: string; // 不一致描述 }; }; // 综合评分和建议 overallScore: number; // 软装综合评分 0-100 strengths: string[]; // 优点 improvements: 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); } /** * 分析单张图片 * @param fastMode 快速模式:跳过专业分析(软装/渲染/后期),只做基础分类和质量评估 */ async analyzeImage( imageUrl: string, file: File, onProgress?: (progress: string) => void, fastMode: boolean = false ): Promise { const startTime = Date.now(); try { // 🔥 如果是Blob URL,转换为Base64(AI无法访问blob URL) let processedUrl = imageUrl; if (imageUrl && imageUrl.startsWith('blob:')) { console.log('🔄 检测到Blob URL,转换为Base64以便AI访问...'); onProgress?.('正在转换图片格式...'); try { processedUrl = await this.blobToBase64(imageUrl); console.log('✅ Base64转换成功,长度:', processedUrl.length); } catch (convertError) { console.error('❌ Base64转换失败,尝试直接使用Blob URL:', convertError); // 如果转换失败,仍然使用原URL } } onProgress?.('正在分析图片内容...'); // 获取图片基础信息 const basicInfo = await this.getImageBasicInfo(file); // 🔥 快速预判断:检查是否为白模图(跳过AI调用) onProgress?.('正在进行快速预判断...'); const quickCheck = await this.quickWhiteModelCheck(processedUrl, file); if (quickCheck.isWhiteModel) { console.log('⚡ 快速预判断:检测到白模图,直接返回结果(跳过AI调用)'); return this.buildWhiteModelResult(file, basicInfo, quickCheck); } onProgress?.('正在进行AI分析...'); // 🚀 优化:合并内容分析和质量分析为一次AI调用(快速模式) if (fastMode) { const combinedAnalysis = await this.analyzeCombinedFast(processedUrl, basicInfo); return combinedAnalysis; } // 非快速模式:使用原有的详细分析 // 使用豆包1.6进行内容分析(使用处理后的URL) const contentAnalysis = await this.analyzeImageContent(processedUrl); onProgress?.('正在评估图片质量...'); // 质量评估(使用处理后的URL) const qualityAnalysis = await this.analyzeImageQuality(processedUrl, basicInfo); onProgress?.('正在生成分析报告...'); // 判断建议阶段 const suggestedStage = this.determineSuggestedStage(contentAnalysis, qualityAnalysis); // 🔥 快速模式:跳过专业分析,直接返回基础结果 let softDecorAnalysis: ImageAnalysisResult['softDecorAnalysis'] | undefined; let renderingAnalysis: ImageAnalysisResult['renderingAnalysis'] | undefined; let postProcessAnalysis: ImageAnalysisResult['postProcessAnalysis'] | undefined; if (!fastMode) { // 🔥 如果是软装阶段,进行专业软装分析 if (suggestedStage === 'soft_decor' || contentAnalysis.category === 'soft_decor') { onProgress?.('正在进行软装专业分析...'); try { softDecorAnalysis = await this.analyzeSoftDecor(imageUrl, file, basicInfo); } catch (error) { console.warn('⚠️ 软装专业分析失败,跳过此步骤:', error); } } // 🔥 如果是渲染阶段,进行专业渲染分析 if (suggestedStage === 'rendering' || contentAnalysis.category === 'rendering') { onProgress?.('正在进行渲染专业分析...'); try { renderingAnalysis = await this.analyzeRendering(imageUrl, file, basicInfo); } catch (error) { console.warn('⚠️ 渲染专业分析失败,跳过此步骤:', error); } } // 🔥 如果是后期处理阶段,进行专业后期处理分析 if (suggestedStage === 'post_process' || contentAnalysis.category === 'post_process') { onProgress?.('正在进行后期处理专业分析...'); try { postProcessAnalysis = await this.analyzePostProcess(imageUrl, file, basicInfo); } catch (error) { console.warn('⚠️ 后期处理专业分析失败,跳过此步骤:', error); } } } // 综合分析结果 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: suggestedStage, suggestedReason: this.generateSuggestionReason(contentAnalysis, qualityAnalysis), softDecorAnalysis: softDecorAnalysis, // 🔥 添加软装专业分析结果 renderingAnalysis: renderingAnalysis, // 🔥 添加渲染专业分析结果 postProcessAnalysis: postProcessAnalysis, // 🔥 添加后期处理专业分析结果 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); }); } /** * 🔥 快速预判断:检查是否为白模图(不调用AI,速度极快) * 通过图片像素统计快速判断,如果明显是白模图则直接返回 */ private async quickWhiteModelCheck(imageUrl: string, file: File): Promise<{ isWhiteModel: boolean; confidence: number; colorVariance: number; grayPercentage: number; }> { return new Promise((resolve) => { const img = new Image(); img.crossOrigin = 'anonymous'; img.onload = () => { try { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); if (!ctx) { resolve({ isWhiteModel: false, confidence: 0, colorVariance: 0, grayPercentage: 0 }); return; } // 缩小图片以加快分析(采样200x200) const sampleSize = 200; canvas.width = sampleSize; canvas.height = sampleSize; ctx.drawImage(img, 0, 0, sampleSize, sampleSize); const imageData = ctx.getImageData(0, 0, sampleSize, sampleSize); const pixels = imageData.data; let grayPixels = 0; let colorfulPixels = 0; let totalVariance = 0; const sampleInterval = 4; // 每4个像素采样1个 for (let i = 0; i < pixels.length; i += 4 * sampleInterval) { const r = pixels[i]; const g = pixels[i + 1]; const b = pixels[i + 2]; const a = pixels[i + 3]; if (a < 128) continue; // 跳过透明像素 // 计算RGB差异 const maxRGB = Math.max(r, g, b); const minRGB = Math.min(r, g, b); const rgbDiff = maxRGB - minRGB; totalVariance += rgbDiff; // 判断是否为灰色(RGB差异<15认为是灰色) if (rgbDiff < 15) { grayPixels++; } else { colorfulPixels++; } } const totalPixels = grayPixels + colorfulPixels; const grayPercentage = totalPixels > 0 ? (grayPixels / totalPixels) * 100 : 0; const avgVariance = totalPixels > 0 ? totalVariance / totalPixels : 0; // 🔥 判断标准(再次优化 - 更宽松,提高白模识别率): // 1. 灰色像素占比 > 70%(降低阈值,容忍更多浅色材质) // 2. RGB平均差异 < 30(增加阈值,容忍木纹等浅色纹理) const isWhiteModel = grayPercentage > 70 && avgVariance < 30; const confidence = isWhiteModel ? Math.min(98, 70 + grayPercentage / 3) : 0; console.log('⚡ 快速预判断结果:', { 灰色占比: `${grayPercentage.toFixed(1)}%`, RGB差异: avgVariance.toFixed(1), 是否白模: isWhiteModel, 置信度: `${confidence}%` }); resolve({ isWhiteModel, confidence, colorVariance: avgVariance, grayPercentage }); } catch (error) { console.warn('快速预判断失败,将使用完整分析:', error); resolve({ isWhiteModel: false, confidence: 0, colorVariance: 0, grayPercentage: 0 }); } }; img.onerror = () => { resolve({ isWhiteModel: false, confidence: 0, colorVariance: 0, grayPercentage: 0 }); }; img.src = imageUrl; }); } /** * 🔥 构建白模图分析结果(快速返回,不调用AI) */ private buildWhiteModelResult( file: File, basicInfo: { dimensions: { width: number; height: number }; dpi?: number }, quickCheck: { confidence: number; grayPercentage: number; colorVariance: number } ): ImageAnalysisResult { const megapixels = Math.round((basicInfo.dimensions.width * basicInfo.dimensions.height) / 1000000 * 100) / 100; // 🔥 根据像素数量转换为pixelDensity字符串类型 let pixelDensityLevel: 'low' | 'medium' | 'high' | 'ultra_high' = 'medium'; if (megapixels < 2) { pixelDensityLevel = 'low'; } else if (megapixels < 8) { pixelDensityLevel = 'medium'; } else if (megapixels < 20) { pixelDensityLevel = 'high'; } else { pixelDensityLevel = 'ultra_high'; } return { fileName: file.name, fileSize: file.size, dimensions: basicInfo.dimensions, quality: { score: 75, level: 'medium', pixelDensity: pixelDensityLevel, detailLevel: 'basic', // 白模细节等级为basic sharpness: 70, brightness: 75, contrast: 70, textureQuality: 40, // 白模纹理质量低 colorDepth: 50 }, content: { category: 'white_model', confidence: quickCheck.confidence, spaceType: '未识别', // 白模图难以准确识别空间类型 description: `这是一张白模图(SketchUp/3ds Max模型)。整体采用统一的灰色材质(灰色占比${quickCheck.grayPercentage.toFixed(0)}%),无装饰性色彩和真实纹理。可能包含家具体块和灯光效果,但材质为简单的漫反射表面。`, tags: ['白模', 'SketchUp', '模型', '灰色材质', '无纹理'], isArchitectural: true, hasInterior: true, hasFurniture: true, // 白模可以有家具 hasLighting: true, // 白模可以有灯光 hasColor: false, // 无装饰性色彩 hasTexture: false // 无真实纹理 }, technical: { format: file.type, colorSpace: 'sRGB', dpi: basicInfo.dpi || 72, aspectRatio: this.calculateAspectRatio(basicInfo.dimensions.width, basicInfo.dimensions.height), megapixels: megapixels }, suggestedStage: 'white_model', suggestedReason: `快速识别:灰色占比${quickCheck.grayPercentage.toFixed(0)}%,RGB差异${quickCheck.colorVariance.toFixed(1)},判定为白模阶段`, analysisTime: 50, // 快速分析,约50ms analysisDate: new Date().toISOString() }; } /** * 🚀 快速模式:合并内容和质量分析为一次AI调用(速度提升50%+) */ private async analyzeCombinedFast( imageUrl: string, basicInfo: { dimensions: { width: number; height: number }; dpi?: number } ): Promise { const startTime = Date.now(); const prompt = `你是室内设计图分类专家,请快速分析这张图片的内容和质量,只输出JSON。 JSON格式: { "category": "white_model或soft_decor或rendering或post_process", "confidence": 90, "spaceType": "客厅或卧室等", "description": "简短描述", "hasColor": true, "hasTexture": true, "hasLighting": true, "qualityScore": 85, "qualityLevel": "high", "sharpness": 80, "textureQuality": 85 } 快速判断规则(严格执行): - white_model: 统一灰白色/浅色,无材质纹理细节(可有家具和灯光) - soft_decor: 有真实材质纹理(木纹/布纹),有装饰色彩,但CG感不强 ⚠️ 关键:软装可以有灯光!重点是材质真实但CG渲染感不强 - rendering: 有材质纹理,有装饰色彩,CG计算机渲染感明显(V-Ray/3dsMax) ⚠️ 区分:rendering = CG感明显(能看出是3D渲染),质量70-89分 - post_process: 照片级真实感(看起来像真实拍摄),质量≥90分 ⚠️ 区分:post_process = 照片级(不是普通CG渲染)`; const output = `{"category":"rendering","confidence":92,"spaceType":"卧室","description":"现代卧室","hasColor":true,"hasTexture":true,"hasLighting":true,"qualityScore":85,"qualityLevel":"high","sharpness":80,"textureQuality":85}`; try { console.log(`⏱️ [快速分析] 开始AI调用,图片Base64大小: ${(imageUrl.length / 1024 / 1024).toFixed(2)} MB`); // 🚀 添加30秒超时机制 const aiPromise = this.callCompletionJSON( prompt, output, undefined, 2, { model: this.MODEL, vision: true, images: [imageUrl], max_tokens: 800 // 确保返回完整结果(避免截断) } ); const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('AI分析超时(60秒)')), 60000); // 🔥 增加到60秒,防止大图超时 }); const result = await Promise.race([aiPromise, timeoutPromise]) as any; // 构建完整结果 const megapixels = Math.round((basicInfo.dimensions.width * basicInfo.dimensions.height) / 1000000 * 100) / 100; const analysisTime = Date.now() - startTime; console.log(`✅ [快速分析] AI调用完成,耗时: ${(analysisTime / 1000).toFixed(2)}秒`); console.log(`📊 [快速分析] AI返回结果:`, { 阶段分类: result.category, 置信度: `${result.confidence}%`, 空间类型: result.spaceType, 有颜色: result.hasColor, 有纹理: result.hasTexture, 有灯光: result.hasLighting, 质量分数: result.qualityScore }); return { fileName: '', fileSize: 0, dimensions: basicInfo.dimensions, quality: { score: result.qualityScore || 75, level: result.qualityLevel || 'medium', sharpness: result.sharpness || 75, brightness: 70, contrast: 75, detailLevel: 'basic', pixelDensity: megapixels >= 2 ? 'high' : 'medium', textureQuality: result.textureQuality || 75, colorDepth: 75 }, content: { category: result.category || 'rendering', confidence: result.confidence || 80, spaceType: result.spaceType || '未识别', description: result.description || '室内设计图', tags: [], isArchitectural: true, hasInterior: true, hasFurniture: true, hasLighting: result.hasLighting !== false, hasColor: result.hasColor !== false, hasTexture: result.hasTexture !== false }, technical: { format: 'image/jpeg', colorSpace: 'sRGB', dpi: basicInfo.dpi || 72, aspectRatio: this.calculateAspectRatio(basicInfo.dimensions.width, basicInfo.dimensions.height), megapixels: megapixels }, suggestedStage: result.category || 'rendering', suggestedReason: `快速分析:${result.category},置信度${result.confidence}%`, analysisTime: analysisTime, analysisDate: new Date().toISOString() }; } catch (error: any) { const analysisTime = Date.now() - startTime; console.error(`❌ [快速分析] 失败 (耗时${(analysisTime / 1000).toFixed(2)}秒):`, { 错误类型: error?.name, 错误信息: error?.message, 是否超时: error?.message?.includes('超时'), 图片大小: `${(imageUrl.length / 1024 / 1024).toFixed(2)} MB` }); throw error; } } /** * 🔥 超快速分析图片内容(极简版:30秒内返回) */ private async analyzeImageContent(imageUrl: string): Promise { const prompt = `你是室内设计图分类专家,请仔细分析这张图片,只输出JSON,不要解释。 JSON格式: { "category": "white_model或soft_decor或rendering或post_process", "confidence": 90, "spaceType": "客厅或卧室或餐厅或厨房或卫生间或书房", "description": "一句话描述", "tags": ["标签1", "标签2"], "isArchitectural": true, "hasInterior": true, "hasFurniture": true, "hasLighting": true, "hasColor": true, "hasTexture": true } ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 🔥 阶段判断规则(按顺序严格执行) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 【第1优先级】white_model(白模) 核心特征: ✅ 材质统一光滑:全部是统一的浅色漆面/灰色漆面 ✅ 无材质细节:看不到木纹、布纹、石材纹理、金属拉丝等细节 ✅ 可以有家具、灯光、阴影(这不影响白模判断!) ✅ 可以有浅色(浅木色、浅灰色、米白色),只要材质统一光滑 ❌ 典型错误:把"浅色统一材质"误判为"有装饰色彩" ⚠️ 关键:如果所有表面都是统一的光滑漆面(无纹理细节),就是白模! 判断标准: - hasColor = false(统一浅色≠装饰色彩) - hasTexture = false(光滑漆面≠真实纹理) - hasLighting = true/false(有无灯光不影响) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 【第2优先级】soft_decor(软装) 核心特征: ✅ 有真实材质纹理:能看到木纹、布纹、石材纹理等细节 ✅ 有装饰色彩:不同材质有不同颜色(木色、布色、石色) ❌ 灯光效果弱:光影不明显,无强烈高光 判断标准: - hasColor = true(有装饰色彩) - hasTexture = true(有材质纹理) - hasLighting = false/弱(灯光效果一般) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 【第3优先级】rendering(渲染) 核心特征: ✅ CG计算机渲染图:3ds Max、SketchUp、V-Ray等软件渲染 ✅ 有真实材质纹理(木纹、布纹清晰) ✅ 有装饰色彩(多种材质颜色) ✅ 灯光效果明显:能看到明显的光影、高光、阴影 ❌ 但质量中等:能看出是CG,不是真实照片 ⚠️ 关键区分: - 渲染图 = CG感明显,质量70-89分 - 照片 = 照片级真实,质量≥90分 判断标准: - hasColor = true - hasTexture = true - hasLighting = true(灯光明显) - 质量分数: 70-89分 - CG感明显(不是真实照片) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 【第4优先级】post_process(后期/照片级参考图) 核心特征: ✅ 照片级真实感:看起来像真实拍摄的照片,不是CG ✅ 极致材质纹理:超清晰的木纹、布纹、金属拉丝 ✅ 强烈色彩氛围:丰富的色彩层次、环境反射、色彩融合 ✅ 完美灯光效果:精致的光晕、柔和过渡、环境光反射 ✅ 超高质量:接近或达到摄影级质量 ⚠️ 重要: - 真实照片 = post_process(即使是客户发的参考图) - 照片级渲染 = post_process(后期精修到照片级) - CG渲染 = rendering(能看出是CG) 判断标准: - hasColor = true - hasTexture = true(超清晰) - hasLighting = true(完美) - 质量分数: 90-100分 - 照片级真实感(不是普通CG渲染) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ⚠️ 最关键的区分要点 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 白模 vs 软装/渲染: - 白模:表面光滑,看不到纹理细节(即使有浅色) - 软装/渲染:能看到清晰的木纹、布纹、石材纹理 软装 vs 渲染: - 软装:材质有纹理,但灯光效果弱(无明显光影) - 渲染:材质有纹理 + 明显的灯光光影效果(但是CG) 渲染 vs 后期: - 渲染:CG计算机渲染,能看出是CG(质量70-89分) - 后期:照片级真实感,像真实拍摄的照片(质量≥85分) ⚠️ 最关键: - 如果看起来像真实照片(不是CG) → post_process - 如果是CG渲染图(能看出是3D渲染) → rendering ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 请仔细观察图片,严格按照以上规则判断!`; const output = `{"category":"rendering","confidence":92,"spaceType":"卧室","description":"现代卧室","tags":["卧室","现代"],"isArchitectural":true,"hasInterior":true,"hasFurniture":true,"hasLighting":true,"hasColor":true,"hasTexture":true}`; try { const result = await this.callCompletionJSON( prompt, output, undefined, // 移除进度回调,加快速度 2, { model: this.MODEL, vision: true, images: [imageUrl] } ); // 🔥 确保返回完整的字段 console.log('✅ AI分析成功返回:', { 类别: result.category, 置信度: result.confidence, 空间类型: result.spaceType || '未识别', 有颜色: result.hasColor, 有纹理: result.hasTexture, 有灯光: result.hasLighting }); return result || { category: 'unknown', confidence: 0, spaceType: '未识别', description: '无法识别图片内容', tags: [], isArchitectural: false, hasInterior: false, hasFurniture: false, hasLighting: false, hasColor: false, hasTexture: false }; } catch (error: any) { console.error('❌ AI内容分析失败 - 详细错误:', { 错误类型: error?.constructor?.name, 错误信息: error?.message, 错误代码: error?.code || error?.status, 图片URL: imageUrl, 错误堆栈: error?.stack?.substring(0, 200) }); // 🔥 确保错误返回也包含完整字段 return { category: 'unknown', confidence: 0, spaceType: '未识别', description: `内容分析失败: ${error?.message || '未知错误'}`, tags: [], isArchitectural: false, hasInterior: false, hasFurniture: false, hasLighting: false, hasColor: false, hasTexture: 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, undefined, // 移除进度回调,提升分析速度 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' { // 🔥 提取关键特征(确保布尔值正确) const hasColor = content.hasColor === true; const hasTexture = content.hasTexture === true; const hasFurniture = content.hasFurniture === true; const hasLighting = content.hasLighting === true; const megapixels = quality.pixelDensity; const detailLevel = quality.detailLevel; const qualityScore = quality.score; const textureQuality = quality.textureQuality; console.log('🎯 阶段判断依据:', { AI类别: content.category, AI置信度: content.confidence, 空间类型: content.spaceType || '未识别', 像素密度: megapixels, 精细程度: detailLevel, 质量分数: qualityScore, 纹理质量: textureQuality, 有家具: hasFurniture, 有灯光: hasLighting, 有色彩: hasColor, 有纹理: hasTexture }); // 🔥 调试:打印原始content对象 console.log('🔍 原始AI返回:', JSON.stringify(content, null, 2)); // 🔥 关键规则1:白模判断(最高优先级!) // 白膜的核心:统一材质 + 无装饰彩色 + 无真实纹理(可以有灯光和家具!) if (!hasColor && !hasTexture) { console.log('🟢 【白模优先规则】材质符合白模特征:无装饰彩色 + 无真实纹理'); // 🔥 只要无彩色无纹理,就判定为白模(不再考虑其他条件) console.log('✅ 判定为白模阶段(最高优先级)'); return 'white_model'; } // 🔥 关键规则2:后期处理判断(第二优先级) // 超高质量 + AI高置信度 = 后期处理 if (qualityScore >= 90 && content.category === 'post_process' && content.confidence >= 80) { console.log('✅ 判定为后期处理阶段:超高质量(≥90分) + AI高置信度判定为后期'); return 'post_process'; } // 🔥 质量特别高也可能是后期(即使AI不确定) if (qualityScore >= 92 && hasColor && hasTexture && hasLighting) { console.log('✅ 判定为后期处理阶段:质量极高(≥92分) + 完整特征'); return 'post_process'; } // 🔥 关键规则3:渲染 vs 软装判断 // 有彩色和纹理(不是白模),根据灯光效果、质量、CG感判断 if (hasColor && hasTexture) { console.log('🔵 有装饰性色彩和真实纹理,判断软装/渲染/后期'); // 🔥 优先判断:照片级质量(≥90分)= 后期/照片 if (qualityScore >= 90) { console.log('✅ 判定为后期处理阶段:照片级质量(≥90分),可能是照片或后期精修'); return 'post_process'; } // 🔥 次优先:AI高置信度判定为post_process if (content.category === 'post_process' && content.confidence >= 85 && qualityScore >= 85) { console.log('✅ 判定为后期处理阶段:AI高置信度+质量85+分'); return 'post_process'; } // 🔥 关键改进:AI明确判定为软装时,优先采用 if (content.category === 'soft_decor' && content.confidence >= 75) { console.log('✅ 判定为软装阶段:AI高置信度判定为软装'); return 'soft_decor'; } // 高质量 + 强灯光 + AI判定为渲染 = 渲染 if (hasLighting && qualityScore >= 70 && content.category === 'rendering') { console.log('✅ 判定为渲染阶段:有彩色材质/纹理 + 强灯光 + AI判定为渲染'); return 'rendering'; } // 中等质量 + 弱灯光 = 软装 if (!hasLighting || qualityScore < 75) { console.log('✅ 判定为软装阶段:有彩色材质/纹理 + 灯光弱/质量中等'); return 'soft_decor'; } // 🔥 默认:根据AI判定或默认渲染 if (content.category === 'soft_decor') { console.log('✅ 判定为软装阶段:AI判定(默认)'); return 'soft_decor'; } console.log('✅ 判定为渲染阶段:有彩色材质/纹理(默认)'); return 'rendering'; } // 🔥 关键规则4:只有彩色或只有纹理(罕见情况) if (hasColor || hasTexture) { console.log('⚠️ 只有彩色或只有纹理(罕见),根据灯光判断'); if (hasLighting && qualityScore >= 75) { console.log('✅ 判定为渲染阶段:有灯光 + 中高质量'); return 'rendering'; } else { console.log('✅ 判定为软装阶段:灯光弱或质量中等'); return 'soft_decor'; } } // 🔥 兜底逻辑(理论上不应该走到这里) console.log('⚠️ 未命中主要规则,使用AI结果或默认渲染'); // 如果AI有高置信度的判断,使用AI结果 if (content.confidence > 80 && content.category !== 'unknown') { console.log(`✅ 兜底:采用AI高置信度(${content.confidence}%)判定: ${content.category}`); return content.category as any; } // 最终兜底:默认渲染 console.log('✅ 兜底:默认判定为渲染阶段'); return 'rendering'; // 旧逻辑(已废弃): // if (qualityScore >= 70) { // return 'rendering'; // ✗ 错误:白模图也可能高质量 // } else if (qualityScore >= 50) { // return 'soft_decor'; // } else { // 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; } /** * 🔥 软装专业分析(基于行业标准的多维度分析) * 包含:材质、灯光、颜色、像素、整体适配性五大维度 */ async analyzeSoftDecor( imageUrl: string, file: File, basicInfo?: { dimensions: { width: number; height: number } } ): Promise { console.log('🎨 开始软装专业分析...'); if (!basicInfo) { basicInfo = await this.getImageBasicInfo(file); } const prompt = `你是一位资深的室内软装设计分析专家。请基于以下专业标准对这张软装图片进行全面、精确的多维度分析: **一、材质维度分析** 识别空间内的核心材质(如水泥、实木、藤编、皮革、大理石、玻璃、金属等): - 每种材质的占比是否均衡? - 硬材质(水泥柱、大理石台面、金属)与软材质(藤编椅、皮革沙发、布艺)如何形成"冷暖/刚柔"的视觉平衡? - 材质的原生肌理(如水泥的粗糙感、实木的木纹、藤编的编织纹理)是否被清晰呈现?有无"材质同质化"问题? - 不同区域的同类材质(如餐桌木面与柜体木面、水泥柱与地面)是否形成视觉关联? **二、灯光维度分析** 分析软装与灯光的互动效果: - 自然光(窗户)与人工光(条形吊灯、壁灯、筒灯)的分布是否合理?主光源、辅助光的层次是否清晰? - 灯光色温(如暖白光)是否与软装材质(如木色、藤编)的质感匹配?有无"色温冲突"(如冷光配暖材质)? - 灯光是否突出软装重点(如餐桌的光泽、藤编椅的纹理)?明暗对比是否自然(暗部有细节、亮部不曝)? - 灯光营造的氛围(如静谧感)是否与空间功能(客餐厅、厨房)的使用场景契合? **三、颜色维度分析** 拆解软装的色彩系统: - 主色调、辅助色、点缀色的占比是否符合"6:3:1"原则?请详细列出各色彩及占比。 - 整体色调(低饱和、暖调)是否统一?不同区域的色彩是否存在"跳脱感"? - 颜色是否强化了材质质感(如木色的暖调+实木的温润、水泥灰的冷调+水泥的粗粝)? - 冷暖色(木色/藤编的暖 vs 水泥/黑色的冷)的占比是否均衡?有无"冷暖失衡"问题? **四、像素维度评价** - 图片像素是否≥1920×1080px(2K)?放大后软装细节(如藤编纹理、木纹)是否清晰? - 图片是否为无损格式(如PNG/TIF)?有无压缩导致的"模糊/噪点"? - 分辨率是否≥72dpi(屏幕展示)/300dpi(打印)? - 软装的微小元素(如玻璃器皿的纹理、餐具的细节)是否被清晰捕捉? **五、整体适配性评估** - 软装风格(如侘寂、工业混搭、现代简约)是否贯穿所有区域?有无"风格割裂"? - 家具尺寸(如餐桌长度、沙发体量)与空间层高/面积是否协调?有无"过大/过小"导致的空间压抑/空洞? - 软装是否兼顾实用性(如储物、动线流畅)与装饰性?请举例说明功能与美学的平衡方式。 - 软装传递的情感基调(松弛、质朴、温馨、静谧)是否在所有区域统一? 请按以下JSON格式输出分析结果(确保所有字段都填写完整):`; const outputSchema = `{ "materialDimension": { "materialTypes": [ { "name": "实木", "proportion": 30, "area": "餐桌、柜体" }, { "name": "水泥", "proportion": 25, "area": "立柱、墙面" }, { "name": "藤编", "proportion": 15, "area": "餐椅" }, { "name": "大理石", "proportion": 15, "area": "台面" }, { "name": "玻璃", "proportion": 10, "area": "器皿、窗户" }, { "name": "金属", "proportion": 5, "area": "灯具、五金" } ], "materialBalance": "材质占比相对均衡,主材实木与水泥形成对比,辅材藤编、大理石、玻璃丰富层次,无明显失衡。", "textureContrast": { "hardMaterials": ["水泥立柱", "大理石台面", "玻璃"], "softMaterials": ["实木餐桌", "藤编椅", "布艺装饰"], "contrastEffect": "硬材质(水泥的粗粝、大理石的冷峻)与软材质(实木的温润、藤编的柔和)形成'冷暖对比'和'刚柔平衡',营造侘寂风格的质朴感与精致感并存。" }, "textureDetails": { "clarity": "肌理呈现清晰,水泥立柱的粗糙斑驳、实木的自然木纹、藤编的编织纹理均可辨识,无模糊或失真。", "homogenization": false, "description": "各材质保持独特肌理:水泥呈现原生粗糙感,实木纹理自然流畅,藤编编织层次分明,大理石光泽温润,玻璃透明通透,无材质同质化问题。" }, "materialEcho": "实木元素在餐桌与柜体间呼应,水泥在立柱与墙面间延续,形成视觉统一;藤编椅与木色系呼应,强化暖调基底。" }, "lightingDimension": { "lightSources": { "natural": ["客厅落地窗", "厨房侧窗"], "artificial": ["餐厅条形吊灯", "厨房筒灯", "客厅壁灯"], "distribution": "光源分布合理,自然光覆盖主要活动区,人工光补充暗部,无明显死角。", "hierarchy": "主光源为餐厅吊灯与自然光,辅助光为筒灯与壁灯,层次清晰,形成视觉焦点。" }, "colorTemperature": { "temperature": "暖白光(约3000-3500K)", "materialMatch": "暖白光与实木、藤编等暖色材质匹配度高,强化温润质感;与水泥、大理石冷材质形成对比但不冲突。", "conflict": false }, "lightShadow": { "focusPoints": ["餐桌木纹光泽", "藤编椅纹理", "大理石台面反光"], "contrastNaturalness": "明暗对比自然,亮部(餐桌、台面)不曝光,暗部(水泥柱背面)保留细节,过渡柔和。", "shadowQuality": "阴影自然,水泥柱投影清晰但不生硬,符合物理光照逻辑。" }, "atmosphereMatch": "灯光营造静谧、温馨氛围,与客餐厅休闲功能、厨房实用功能契合度高。" }, "colorDimension": { "colorHierarchy": { "primary": [ { "color": "米白/原木色", "proportion": 60 } ], "secondary": [ { "color": "水泥灰", "proportion": 25 }, { "color": "黑色(家具框架)", "proportion": 5 } ], "accent": [ { "color": "玻璃透明", "proportion": 5 }, { "color": "绿植点缀", "proportion": 3 }, { "color": "花瓶蓝调", "proportion": 2 } ], "ratio631": true, "ratio631Analysis": "主色调米白/木色占比约60%,辅助色水泥灰+黑色约30%,点缀色玻璃+绿植+蓝调约10%,符合6:3:1原则,色彩层次分明。" }, "colorTone": { "overallTone": "低饱和暖调为主,米白、木色、藤编营造温润基底,水泥灰、黑色提供冷调平衡。", "consistency": true, "jumpingIssue": false }, "colorMaterialRelation": "木色的暖调强化了实木的温润质感,水泥灰的冷调凸显了水泥的粗粝质朴,藤编的黄调增添了手工感,色彩与材质相互强化。", "colorBalance": { "warmColors": ["米白", "原木色", "藤编黄", "暖白光"], "coolColors": ["水泥灰", "黑色", "玻璃透明"], "balance": "暖色占比约65%,冷色约35%,冷暖平衡合理,暖色主导但不失稳重,冷色点缀但不压抑。", "imbalanceIssue": false } }, "pixelDimension": { "pixelSize": { "width": 2400, "height": 1600, "meets2K": true, "detailClarity": "放大后藤编纹理、木纹、水泥斑驳均清晰可辨,无明显像素化或模糊。" }, "imageQuality": { "format": "JPEG", "isLossless": false, "compressionIssue": false, "qualityDescription": "画质良好,虽为JPEG有损格式,但压缩率适中,无明显噪点或色块,细节保留完整。" }, "resolution": { "dpi": 72, "meetsScreen": true, "meetsPrint": false }, "detailPresentation": "微小元素如玻璃器皿的透明质感、餐具的金属光泽、绿植叶脉均被清晰捕捉,细节呈现优秀。" }, "overallAdaptability": { "styleConsistency": { "style": "侘寂 + 工业混搭", "consistency": true, "fragmentation": false }, "proportionMatch": { "furnitureSizes": [ { "name": "餐桌", "size": "长约2.2m", "suitability": "与层高2.8m、开放式空间协调,无压抑感" }, { "name": "藤编椅", "size": "高约0.45m", "suitability": "与餐桌高度匹配,体量适中" }, { "name": "沙发", "size": "三人位", "suitability": "与客厅面积协调,无空洞感" } ], "spaceCoordination": "家具尺寸与空间层高、面积协调性高,餐桌长度适配开放式布局,沙发体量填充客厅但不拥挤。", "sizeIssue": false }, "functionAesthetics": { "practicalExamples": ["餐边柜提供储物", "开放式布局优化动线", "厨房台面满足操作需求"], "decorativeExamples": ["藤编椅增添手工感", "玻璃器皿点缀", "绿植提升自然氛围"], "balanceMethod": "功能性通过储物、动线优化体现,装饰性通过材质对比、色彩搭配、手工元素呈现,两者相互融合,实用与美观并重。" }, "atmosphereConsistency": { "emotionalTone": "松弛、质朴、静谧、温馨", "consistency": true, "inconsistencyDescription": null } }, "overallScore": 92, "strengths": [ "材质搭配丰富且均衡,硬软对比明显,呈现侘寂美学", "色彩符合6:3:1原则,冷暖平衡合理,层次分明", "灯光层次清晰,暖白光与材质匹配度高,氛围营造到位", "家具尺寸与空间协调,功能与美学平衡良好", "风格统一,侘寂+工业混搭贯穿始终,无割裂感" ], "improvements": [ "像素分辨率为72dpi,满足屏幕展示但不适合高精度打印,建议提升至300dpi", "JPEG格式为有损压缩,建议保存PNG/TIF无损版本以保留最佳细节", "点缀色占比略少,可适当增加绿植或装饰品丰富视觉层次" ] }`; try { const result = await this.callCompletionJSON( prompt, outputSchema, (content) => { console.log('🎨 软装分析进度:', content?.length || 0); }, 2, { model: this.MODEL, vision: true, images: [imageUrl] } ); console.log('✅ 软装专业分析完成'); return result; } catch (error) { console.error('❌ 软装分析失败:', error); return undefined; } } /** * 🔥 渲染专业分析(基于行业标准的三大维度分析) * 包含:像素清晰度、色彩精细度、灯光氛围三大维度 */ async analyzeRendering( imageUrl: string, file: File, basicInfo?: { dimensions: { width: number; height: number } } ): Promise { console.log('🎬 开始渲染专业分析...'); if (!basicInfo) { basicInfo = await this.getImageBasicInfo(file); } const prompt = `你是一位资深的室内渲染图质量分析专家。请基于以下专业标准对这张渲染图进行全面、精确的三大维度分析: **一、像素大小与清晰度维度分析** 从渲染图的视觉细节判断像素级别和清晰度: 1. **像素级别判断**: - preview(小图预览级):约800-1200像素宽,适合快速预览 - standard(标准级):约1500-1920像素宽,适合一般展示 - high(高清级):约2000-2500像素宽,适合专业展示 - ultra(超高清级):约3000-4000像素宽,适合印刷 - print(印刷级):≥4000像素宽,适合高精度印刷 2. **细节保留度评估**: - 基础结构清晰度:沙发轮廓、柜体线条、墙面接缝等基础结构是否清晰 - 精细纹理清晰度:藤编座椅的编织纹路、木纹的自然结疤、金属拉丝纹理等精细材质是否清晰 - 边缘锐度:物品边缘、家具线条的锐度是否足够 - 是否存在轻微模糊或像素块感 3. **放大损耗评估**: - 局部放大后(如茶几桌面、桌面物品)是否出现像素块感 - 高频细节(如物品边缘锐度)的衰减程度 - 放大适用性评价 **二、色彩精细程度维度评估** 分析渲染图的色彩风格和精细度: 1. **色彩风格识别**: - 自然低饱和系、高饱和系、单色调系等 - 主导色彩识别(如木色、米白、浅灰等) 2. **色域覆盖分析**: - 色彩空间判断(sRGB、Adobe RGB等) - 饱和度范围(低饱和度、中饱和度、高饱和度) - 色域集中区域 3. **色彩还原精度**: - 材质色彩(如木质柜体、沙发面料、墙面)与真实材质的色差值ΔE评估(参考CQS标准) - ΔE≤2:专业级色彩还原 - ΔE 3-5:中阶写实级色彩还原 - ΔE>5:基础色彩还原 - 不同材质的色彩区分能力 4. **色彩层次过渡**: - 同色系的层次过渡细腻度(如墙面阴影的灰度变化) - 过渡级数评估(是否需要增加过渡层次) 5. **色彩一致性**: - 跨图片/区域的色彩统一性 - 金属、玻璃等材质的反光色彩是否融合环境色(如木色、白色) - 环境色融合细节评价 **三、灯光氛围维度分析** 评估灯光设计和氛围营造: 1. **灯光风格识别**: - 柔和自然系、戏剧化、工业风等灯光风格 - 氛围营造等级(basic/good/excellent/master) 2. **光源类型分析**: - 主光源:窗外漫射自然光、直射光等 - 辅助光源:间接照明(吊顶灯带、墙面壁灯)、装饰光源 3. **光影层次评估**: - 整体明暗对比度(如1:4、1:6等) - 阴影过渡自然度(如沙发底部、柜体侧面) - 核心问题识别: * 光源指向性是否清晰 * 主光源位置是否明确 * 高光区域(如桌面物品、玻璃器皿)的光斑形态是否清晰 * 是否缺乏"硬光点缀"(如窗外直射光的局部亮斑) * 空间立体感是否充足 4. **氛围适配度**: - 灯光色温(如4000K暖白光) - 与空间定位的契合度(如简约舒适、高级奢华等) - 装饰光源的氛围感输出: * 壁灯光晕范围是否足够 * 落地灯效果是否明显 * 是否形成局部柔和光区 5. **优化方向**: - 像素提升建议:是否需要提升至2000+/8K超高清 - 色彩优化建议:色差值ΔE目标、同色系过渡层次增加等 - 灯光优化建议:增加直射光光斑、扩大光晕范围、增强光源指向性等 请按以下JSON格式输出分析结果(确保所有字段都填写完整):`; const outputSchema = `{ "pixelClarityDimension": { "pixelLevel": "preview", "estimatedSize": { "width": 1000, "height": 600, "description": "小图预览级,约1000×600像素,适合渲染阶段快速输出" }, "detailRetention": { "structureClarity": "基础结构(沙发轮廓、柜体线条、墙面接缝)清晰,主体结构完整", "textureClarity": "精细纹理(藤编编织纹路、木纹结疤、金属拉丝)存在轻微模糊,未达到2000+像素精度", "edgeSharpness": "物品边缘锐度中等,主体清晰但精细边缘略显柔和", "blurIssue": true, "blurDescription": "放大后局部区域(如茶几桌面、装饰品细节)存在轻微模糊,高频细节保留不足" }, "scaleLoss": { "pixelBlockEffect": true, "highFrequencyLoss": "局部放大后像素块感明显,高频细节(物品边缘、纹理微结构)衰减较快", "enlargeSuitability": "适合屏幕小尺寸预览,不适合大幅放大或印刷使用" }, "optimizationSuggestions": [ "提升像素至2500像素宽(高清级),保留藤编纹理、木纹结疤等精细材质细节", "增强边缘锐度,消除像素模糊,实现印刷级细节精度", "如需8K超高清,建议提升至3500-4000像素宽" ] }, "colorRefinementDimension": { "colorStyle": "自然低饱和系", "refinementLevel": "intermediate", "colorGamutCoverage": { "dominantColors": ["木色(暖棕/浅柚木)", "米白", "浅灰"], "colorSpace": "sRGB", "saturationRange": "中低饱和度区域,无高饱和色块", "colorDescription": "色域集中在sRGB的中低饱和度区域,以暖色调为主,冷暖平衡" }, "colorAccuracy": { "materialColors": [ { "material": "木质柜体", "colorDescription": "暖棕色,接近真实木材色彩", "deltaE": 3.5 }, { "material": "沙发面料", "colorDescription": "米灰色,与真实布料色差适中", "deltaE": 4.0 }, { "material": "墙面", "colorDescription": "浅灰白色,接近真实涂料色彩", "deltaE": 3.0 } ], "differentiationAbility": "能区分不同材质的色彩差异,但同色系层次感不足", "gradientTransition": { "smoothness": "墙面阴影的灰度变化过渡不够细腻,层次感略显生硬", "gradeLevels": 3 } }, "colorConsistency": { "crossImageConsistency": true, "metallicGlassReflection": "金属、玻璃材质的反光色彩(如餐桌金属腿的冷灰反光)缺乏环境色融合细节", "environmentColorBlend": false, "environmentColorDescription": "金属反光未融合木色/白色环境色,显得略显生硬" }, "optimizationSuggestions": [ "提升色彩还原精度,目标ΔE≤2(专业级)", "增加同色系过渡层次至5-7级(如墙面阴影灰度细分)", "金属/玻璃反光融合环境色(木色/白色),增强材质色彩的真实感与层次感", "确保sRGB色域100%覆盖" ] }, "lightingAtmosphereDimension": { "lightingStyle": "柔和自然系氛围光", "atmosphereLevel": "good", "lightSources": { "primary": [ { "type": "窗外漫射自然光", "position": "落地窗区域", "characteristics": "柔和、均匀,覆盖主要活动区" } ], "auxiliary": [ { "type": "吊顶灯带间接照明", "coverage": "顶部区域", "effectiveness": "补充暗部,光晕范围略小" }, { "type": "墙面壁灯", "coverage": "局部墙面", "effectiveness": "装饰性光源,氛围感输出不足,光晕范围过小" } ] }, "lightShadowHierarchy": { "contrastRatio": "1:4(柔和对比)", "shadowTransition": "阴影过渡自然,沙发底部、柜体侧面阴影柔和", "keyIssues": [ "光源指向性弱,无法明确区分主光源位置", "高光区域(如桌面物品、玻璃器皿)光斑形态模糊", "缺乏硬光点缀(如窗外直射光的局部亮斑)", "空间立体感稍弱" ], "highlightQuality": { "definition": "高光区域清晰度不足,光斑边界模糊", "spotShape": "光斑形态不明确,缺乏清晰的光影轮廓", "hardLightAccent": false, "hardLightDescription": "缺少窗外直射光的硬光点缀,导致空间立体感不足" }, "spatialDepth": "空间立体感稍弱,明暗层次不够丰富" }, "atmosphereAdaptation": { "colorTemperature": "4000K暖白光", "spacePositioning": "符合简约舒适的空间定位", "decorativeLightOutput": { "wallLampHalo": "壁灯光晕范围过小,未形成局部柔和光区", "floorLampEffect": "落地灯效果不明显,氛围感输出不足", "localSoftLightZone": false } }, "optimizationSuggestions": [ "增加15%的窗外直射光光斑(如桌面、沙发扶手区域),增强硬光点缀", "吊顶灯带的间接照明光晕范围扩大至墙面30cm", "壁灯的暖光光晕形成局部柔和光区,增强装饰性光源的氛围感输出", "增强光源指向性,明确主光源位置", "提升空间明暗层次与立体感,保留柔和舒适的整体氛围" ] }, "overallScore": 75, "renderingQualityLevel": "standard", "strengths": [ "基础结构清晰,主体轮廓完整", "色彩风格统一,自然低饱和系营造舒适氛围", "阴影过渡自然,整体明暗柔和", "灯光色温适配,符合空间定位" ], "improvements": [ "像素尺寸建议提升至2500像素宽,增强精细纹理清晰度", "色彩还原精度建议优化至ΔE≤2,增加同色系过渡层次", "增加硬光点缀和光源指向性,提升空间立体感", "金属/玻璃反光需融合环境色,增强真实感" ], "optimizationPrompts": { "pixelOptimization": "8K超高清室内渲染图,2500像素宽,保留藤编纹理、木纹结疤、金属拉丝等精细材质细节,边缘锐度提升,消除像素模糊,实现印刷级细节精度。", "colorOptimization": "自然低饱和色彩体系,sRGB色域100%覆盖,木质材质色差值ΔE≤2,同色系色彩层次增加5级过渡(如墙面阴影的灰度细分),金属/玻璃反光融合环境色(木色/白色),增强材质色彩的真实感与层次感。", "lightingOptimization": "以窗外4000K漫射自然光为主光源,增加15%的直射光光斑(如桌面、沙发扶手区域),吊顶灯带的间接照明光晕范围扩大至墙面30cm,壁灯的暖光光晕形成局部柔和光区,增强光源指向性,提升空间明暗层次与立体感,保留柔和舒适的整体氛围。" } }`; try { const result = await this.callCompletionJSON( prompt, outputSchema, (content) => { console.log('🎬 渲染分析进度:', content?.length || 0); }, 2, { model: this.MODEL, vision: true, images: [imageUrl] } ); console.log('✅ 渲染专业分析完成'); return result; } catch (error) { console.error('❌ 渲染分析失败:', error); return undefined; } } /** * 🔥 后期处理专业分析(基于行业标准,与渲染阶段对比) * 包含:像素清晰度对比、色彩精细度对比、灯光氛围对比、后期新增细节四大维度 */ async analyzePostProcess( imageUrl: string, file: File, basicInfo?: { dimensions: { width: number; height: number } } ): Promise { console.log('🎞️ 开始后期处理专业分析(与渲染阶段对比)...'); if (!basicInfo) { basicInfo = await this.getImageBasicInfo(file); } const prompt = `你是一位资深的室内后期处理图片分析专家。请基于以下专业标准,对这张后期处理图片进行全面的四大维度对比分析(与前期渲染小图对比): **分析框架:对比前期渲染小图与后期成品大图的质变** **一、像素与清晰度维度对比** **前期渲染小图特征**(800-1200像素宽): - 精细纹理(如藤编座椅纹路、木纹结疤)模糊 - 边缘锐度不足 - 存在像素块感 **后期成品大图评估标准**(2000+像素宽): 1. **材质细节清晰度**: - 藤编的编织肌理是否完全清晰 - 木质柜体的自然纹理是否可辨识 - 金属的拉丝质感是否清晰 - 其他精细材质细节 2. **边缘质量**: - 边缘线条是否锐利 - 是否消除像素块感 - 物品轮廓清晰度 3. **印刷/展示适用性**: - 是否满足印刷需求 - 是否适合大幅展示 **质变描述**:从"预览级"到"成品级"的具体提升 **二、色彩精细度维度对比** **前期渲染小图特征**: - 色彩层次单一(同色系过渡仅3级左右) - 材质色差值ΔE≈3-5(中阶写实级) **后期成品大图评估标准**: 1. **色彩层次升级**: - 同色系过渡增加至5-8级(如墙面从亮白到阴影灰的渐变) - 具体的渐变细节描述 2. **材质色彩还原精度**: - 材质色差值ΔE是否≤2(专业级) - 木色的暖棕/浅柚木区分精准度 - 各材质的色彩改进描述 3. **环境色融合**: - 金属/玻璃反光是否融入环境色 - 具体融合示例(如餐桌金属腿反射出的木色光晕) 4. **微色彩细节**: - 新增的微色彩肌理(如藤编座椅的浅黄肌理、装饰陶罐的土棕纹理) - 这些细节如何提升材质真实感 **质变描述**:从"中阶写实"到"高还原质感"的具体提升 **三、灯光氛围维度对比** **前期渲染小图问题**: - 光源指向性弱 - 高光光斑模糊 - 空间立体感不足 **后期成品大图评估标准**: 1. **光源层次明确化**: - 主光源(窗外自然光): * 漫射光描述 * 增加的直射光比例(如15%) * 直射光光斑的具体区域(如沙发扶手、桌面的局部亮区) - 辅助光源(吊顶灯带、壁灯): * 光晕范围扩大情况(如壁灯光晕覆盖墙面30cm) 2. **阴影质感升级**: - 是否保留柔和感 - 是否新增"微硬边阴影"(如柜体底部、物品边缘) - 如何强化空间纵深感 3. **氛围细节补充**: - 是否新增"环境光反射" - 具体反射示例(如地面反射的家具轮廓、墙面反射的灯光暖调) - 空间光感自然度 **质变描述**:从"柔和但平"到"层次化氛围"的具体提升 **四、后期新增细节维度** **前期渲染小图特征**: - 物品陈设仅保留基础轮廓 - 细节模糊(如茶几上的物品模糊) **后期成品大图评估标准**: 1. **生活化细节**: - 识别新增的物品(玻璃杯、书籍、装饰陶罐、植物等) - 每个物品的细节描述(如书籍的封面纹理、植物的枝叶细节、玻璃杯的透明质感) 2. **真实居住感**: - 这些细节如何填充空间的真实居住感 - 生活化氛围营造 **质变描述**:从"基础结构"到"生活感填充"的具体提升 **综合评估**: - 后期处理综合评分(0-100分) - 后期处理质量等级(good/excellent/master/exceptional) - 优点总结 - 与渲染阶段对比总结 请按以下JSON格式输出分析结果(确保所有字段都填写完整):`; const outputSchema = `{ "pixelClarityComparison": { "beforeRendering": { "pixelRange": "800-1200像素宽", "clarityLevel": "预览级", "textureIssues": [ "藤编座椅纹路模糊", "木纹结疤不清晰", "金属拉丝纹理缺失" ], "edgeIssues": [ "边缘锐度不足", "局部像素块感明显", "物品轮廓软化" ] }, "afterPostProcess": { "pixelRange": "2000+像素宽(约2400×1440)", "clarityLevel": "成品级/展示级", "textureQuality": { "details": [ "藤编编织肌理完全清晰,可辨识编织纹路的交错细节", "木质柜体的自然纹理、结疤、年轮均清晰可见", "金属灯具的拉丝质感、光泽细节完整呈现", "布艺装饰的织纹结构清晰" ], "clarity": "材质细节完全清晰,无模糊或像素损耗" }, "edgeQuality": "边缘线条锐利,物品轮廓清晰,无像素块感,边缘过渡自然", "printSuitability": true }, "qualityLeap": "从预览级(800-1200px)提升至成品级(2000+px),材质细节从模糊到完全清晰,边缘从软化到锐利,实现印刷级质量,像素密度提升约67-150%" }, "colorRefinementComparison": { "beforeRendering": { "gradientLevels": 3, "deltaE": 4.0, "colorLayers": "色彩层次单一,同色系过渡生硬,缺乏细腻的灰度变化" }, "afterPostProcess": { "gradientLevels": 7, "deltaE": 1.5, "gradientDetails": [ "墙面从亮白(RGB 245,245,245)到阴影灰(RGB 180,180,180)的7级细腻过渡", "地面从浅灰到暗灰的5级自然渐变", "木质柜体表面的光影过渡增加至6级" ], "materialColorAccuracy": [ { "material": "木质柜体", "improvement": "暖棕色精准度提升,ΔE从3.5降至1.2,浅柚木与深柚木的色相区分更清晰" }, { "material": "沙发面料", "improvement": "米灰色还原度提升,ΔE从4.0降至1.5,布料的冷暖调细分更精准" }, { "material": "墙面涂料", "improvement": "浅灰白色层次感提升,ΔE从3.0降至1.8,阴影区域的灰度细分更丰富" } ], "environmentColorBlend": { "enabled": true, "examples": [ "餐桌金属腿反射出的木色光晕(暖黄调),融合了周边木质家具的环境色", "玻璃器皿反射的墙面灰白色调,与空间色彩协调统一", "地面反射的暖色调灯光,与木质元素的色温相呼应" ] }, "microColorDetails": [ "藤编座椅的浅黄肌理(米黄至淡金的微色差)", "装饰陶罐的土棕纹理(褐色至红棕的自然变化)", "植物叶片的翠绿至深绿的色彩层次", "书籍封面的微妙色彩(米白、浅灰、淡蓝的细微区分)" ] }, "qualityLeap": "从中阶写实(ΔE≈4.0,3级过渡)提升至高还原质感(ΔE≈1.5,7级过渡),色彩层次提升133%,材质色彩还原精度提升至专业级,新增环境色融合与微色彩细节" }, "lightingAtmosphereComparison": { "beforeRendering": { "issues": [ "光源指向性弱,无法明确主光源位置", "高光光斑模糊,缺乏清晰的光影轮廓", "空间立体感不足,明暗层次平淡", "缺乏硬光点缀,氛围单调" ], "atmosphereLevel": "柔和但平淡(good级)" }, "afterPostProcess": { "lightSourceHierarchy": { "primaryLight": { "type": "窗外自然光", "diffuseLight": "柔和的漫射光覆盖主要活动区,保持整体温馨氛围", "directLight": { "percentage": 15, "spotAreas": [ "沙发扶手局部亮区(形成明显光斑)", "餐桌桌面的局部照射区", "茶几表面的高光区域", "装饰画框的边缘反光" ] } }, "auxiliaryLight": { "sources": [ { "type": "吊顶灯带间接照明", "haloExpansion": "光晕范围从原15cm扩大至墙面30cm,形成更柔和的过渡光区" }, { "type": "墙面壁灯", "haloExpansion": "暖光光晕覆盖墙面30cm范围,形成局部柔和光区,氛围感提升" } ] } }, "shadowQualityUpgrade": { "softTransition": true, "microHardEdge": { "enabled": true, "areas": [ "柜体底部的微硬边阴影(强化物体接地感)", "装饰品边缘的清晰阴影轮廓", "家具腿部的投影(增强纵深感)", "墙面装饰的明确投影" ] }, "spatialDepthEnhancement": "通过微硬边阴影与柔和阴影的结合,空间纵深感显著提升,前后景层次分明" }, "atmosphereDetails": { "environmentReflection": { "enabled": true, "examples": [ "地面反射的家具轮廓(如沙发底部、柜体底部的模糊反射)", "墙面反射的灯光暖调(形成二次光源效果)", "玻璃器皿反射的窗外光线", "木质桌面反射的顶部光源" ] }, "naturalness": "环境光反射自然,光影逻辑符合物理规律,空间光感真实且富有层次" } }, "qualityLeap": "从柔和但平(good级)提升至层次化氛围(excellent级),主光源增加15%直射光,辅助光源光晕扩大100%,新增微硬边阴影与环境光反射,空间立体感与光感层次显著提升" }, "postProcessDetailsAddition": { "beforeRendering": { "detailLevel": "基础结构级,仅保留家具主体轮廓", "itemClarity": "茶几上的物品模糊,缺乏细节,装饰品仅保留基础形态" }, "afterPostProcess": { "lifeDetails": [ { "item": "玻璃杯", "description": "透明玻璃杯的光影折射、杯壁厚度、杯口细节完整呈现,杯中液体(水/饮料)的透明质感清晰" }, { "item": "书籍", "description": "书籍封面的纹理(布纹/纸质)、书脊的文字、页面的微妙色差、书角的磨损细节" }, { "item": "装饰陶罐", "description": "陶罐的土棕肌理、手工痕迹、表面的微妙光泽、开口边缘的细节" }, { "item": "植物(枝叶/花卉)", "description": "植物叶片的脉络、叶缘锯齿、枝干的自然弯曲、叶片的翠绿至深绿渐变" }, { "item": "其他装饰品", "description": "如相框的金属边框细节、装饰盘的花纹、蜡烛的质感等" } ], "livingAtmosphere": "通过玻璃杯、书籍、植物等生活化物品的细节填充,空间从'展示型'转变为'居住型',真实居住感显著提升,营造出温馨、有生活气息的家居氛围" "detailEnhancement": "新增10+项生活化细节,从基础陈设到精细物品,细节丰富度提升约200%,空间叙事性增强" }, "qualityLeap": "从基础结构(仅保留轮廓)提升至生活感填充(精细物品细节),新增玻璃杯、书籍、陶罐、植物等10+项生活化元素,空间从展示型转变为居住型,真实感提升150%" }, "overallScore": 95, "postProcessQualityLevel": "master", "strengths": [ "像素密度从预览级提升至成品级,材质细节完全清晰,满足印刷需求", "色彩还原精度达专业级(ΔE≤2),色彩层次从3级提升至7级", "灯光氛围从柔和但平提升至层次化,新增15%直射光与环境光反射", "新增10+项生活化细节,空间真实居住感显著提升", "环境色融合自然,微色彩细节丰富,材质真实感强" ], "comparisonSummary": "后期处理实现了从'预览级渲染小图'到'成品级展示大图'的全方位质变:像素密度提升67-150%(从800-1200px到2000+px),色彩还原精度提升至专业级(ΔE从4.0降至1.5),灯光层次从平淡到丰富(新增15%直射光、微硬边阴影、环境光反射),生活化细节从无到有(新增10+项物品细节),整体从展示型空间转变为居住型空间,真实感与氛围感全面提升。" }`; try { const result = await this.callCompletionJSON( prompt, outputSchema, (content) => { console.log('🎞️ 后期处理分析进度:', content?.length || 0); }, 2, { model: this.MODEL, vision: true, images: [imageUrl] } ); console.log('✅ 后期处理专业分析完成'); return result; } catch (error) { console.error('❌ 后期处理分析失败:', error); return undefined; } } /** * 🚀 压缩图片以加快AI分析速度(大图压缩到1920px宽度) */ private async compressImageForAnalysis(imageUrl: string, maxWidth: number = 1920): Promise { return new Promise((resolve, reject) => { const img = new Image(); img.crossOrigin = 'anonymous'; img.onload = () => { try { // 如果图片宽度 <= maxWidth,无需压缩,直接转Base64 if (img.naturalWidth <= maxWidth) { console.log(`✅ 图片宽度${img.naturalWidth}px ≤ ${maxWidth}px,无需压缩`); // 直接使用原图转Base64 this.blobToBase64Original(imageUrl).then(resolve).catch(reject); return; } // 计算压缩比例 const scale = maxWidth / img.naturalWidth; const newWidth = maxWidth; const newHeight = Math.round(img.naturalHeight * scale); console.log(`🔄 压缩图片: ${img.naturalWidth}x${img.naturalHeight} → ${newWidth}x${newHeight}`); // 创建Canvas进行压缩 const canvas = document.createElement('canvas'); canvas.width = newWidth; canvas.height = newHeight; const ctx = canvas.getContext('2d'); if (!ctx) { reject(new Error('无法创建Canvas上下文')); return; } // 绘制压缩后的图片 ctx.drawImage(img, 0, 0, newWidth, newHeight); // 转换为Base64(JPEG格式,质量85%) const compressedBase64 = canvas.toDataURL('image/jpeg', 0.85); console.log(`✅ 压缩完成,Base64长度: ${(compressedBase64.length / 1024 / 1024).toFixed(2)} MB`); resolve(compressedBase64); } catch (error) { console.error('❌ 图片压缩失败:', error); reject(error); } }; img.onerror = () => { reject(new Error('图片加载失败')); }; img.src = imageUrl; }); } /** * 🔥 将Blob URL转换为Base64(原始方法,供压缩逻辑调用) */ private async blobToBase64Original(blobUrl: string): Promise { try { const response = await fetch(blobUrl); const blob = await response.blob(); return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => { const result = reader.result as string; if (result) { resolve(result); } else { reject(new Error('FileReader返回空结果')); } }; reader.onerror = () => { reject(new Error('FileReader读取失败: ' + reader.error?.message)); }; reader.readAsDataURL(blob); }); } catch (error: any) { console.error('❌ Blob转Base64失败:', error); throw error; } } /** * 🔥 将Blob URL转换为Base64(已优化:自动压缩大图) * AI模型无法访问blob: URL,需要转换为base64格式 */ private async blobToBase64(blobUrl: string): Promise { try { // 🚀 优化:自动压缩大图,加快AI分析速度 return await this.compressImageForAnalysis(blobUrl, 1920); } catch (error: any) { console.error('❌ Blob转Base64失败:', error); throw error; } } /** * 🚀 快速分析交付图片(返回简化JSON) * 专为交付执行阶段优化,快速返回空间和阶段信息 * 格式: {"space":"客厅","stage":"软装"} */ async quickAnalyzeDeliveryImage(imageUrl: string): Promise<{ space: string; stage: string; confidence?: number }> { try { console.log('🚀 [快速分析] 开始分析图片...'); // 调用AI进行快速分析 const analysisResult = await Parse.Cloud.run('ai-quick-delivery-analysis', { imageUrl, analysisType: 'quick_delivery' }); console.log('✅ [快速分析] 分析完成:', analysisResult); // 返回简化的JSON结果 return { space: analysisResult?.space || '未知空间', stage: analysisResult?.stage || 'rendering', confidence: analysisResult?.confidence || 0 }; } catch (error: any) { console.error('❌ [快速分析] 分析失败:', error); // 失败时使用基于文件名的快速判断 return this.quickAnalyzeByFileName(imageUrl); } } /** * 🔥 基于文件名快速分析(兜底方案) * 当AI分析失败时,根据文件名关键词快速判断 */ private quickAnalyzeByFileName(imageUrl: string): { space: string; stage: string; confidence: number } { const fileName = imageUrl.toLowerCase(); // 🔥 阶段判断(优先级:白膜 > 软装 > 渲染 > 后期) let stage = 'rendering'; // 默认渲染 // 白膜关键词(最高优先级) if (fileName.includes('白模') || fileName.includes('bm') || fileName.includes('whitemodel') || fileName.includes('模型') || fileName.includes('建模') || fileName.includes('白膜')) { stage = 'white_model'; } // 软装关键词 else if (fileName.includes('软装') || fileName.includes('rz') || fileName.includes('softdecor') || fileName.includes('家具') || fileName.includes('配饰') || fileName.includes('陈设')) { stage = 'soft_decor'; } // 后期关键词 else if (fileName.includes('后期') || fileName.includes('hq') || fileName.includes('postprocess') || fileName.includes('修图') || fileName.includes('精修') || fileName.includes('调色')) { stage = 'post_process'; } // 渲染关键词(默认) else if (fileName.includes('渲染') || fileName.includes('xr') || fileName.includes('rendering') || fileName.includes('效果图') || fileName.includes('render')) { stage = 'rendering'; } // 🔥 空间判断 let space = '未知空间'; if (fileName.includes('客厅') || fileName.includes('kt') || fileName.includes('living')) { space = '客厅'; } else if (fileName.includes('卧室') || fileName.includes('ws') || fileName.includes('bedroom') || fileName.includes('主卧') || fileName.includes('次卧')) { space = '卧室'; } else if (fileName.includes('餐厅') || fileName.includes('ct') || fileName.includes('dining')) { space = '餐厅'; } else if (fileName.includes('厨房') || fileName.includes('cf') || fileName.includes('kitchen')) { space = '厨房'; } else if (fileName.includes('卫生间') || fileName.includes('wsj') || fileName.includes('bathroom') || fileName.includes('浴室') || fileName.includes('厕所')) { space = '卫生间'; } else if (fileName.includes('书房') || fileName.includes('sf') || fileName.includes('study')) { space = '书房'; } else if (fileName.includes('阳台') || fileName.includes('yt') || fileName.includes('balcony')) { space = '阳台'; } else if (fileName.includes('玄关') || fileName.includes('xg') || fileName.includes('entrance')) { space = '玄关'; } console.log(`🔍 [文件名分析] ${fileName} → 空间: ${space}, 阶段: ${stage}`); return { space, stage, confidence: 70 // 基于文件名的分析,置信度设为70% }; } }