| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798 | 
							- import { Injectable } from '@angular/core';
 
- import { HttpClient } from '@angular/common/http';
 
- import { Observable, BehaviorSubject, throwError, forkJoin, of } from 'rxjs';
 
- import { catchError, map } from 'rxjs/operators';
 
- import { FormAnalysisService } from './form-analysis.service';
 
- import { TextureAnalysisService } from './texture-analysis.service';
 
- import { PatternAnalysisService } from './pattern-analysis.service';
 
- import { LightingAnalysisService } from './lighting-analysis.service';
 
- export interface UploadedFile {
 
-   id: string;
 
-   name: string;
 
-   url: string;
 
-   size?: number;
 
-   type?: string;
 
-   preview?: string;
 
- }
 
- export interface ColorAnalysisResult {
 
-   colors: Array<{
 
-     hex: string;
 
-     rgb: { r: number; g: number; b: number };
 
-     percentage: number;
 
-     name?: string; // 添加可选的name属性
 
-   }>;
 
-   originalImage: string;
 
-   mosaicImage: string;
 
-   reportPath: string;
 
-   // 新增增强分析结果
 
-   enhancedAnalysis?: EnhancedColorAnalysis;
 
-   // 新增其他分析结果
 
-   formAnalysis?: any;
 
-   textureAnalysis?: any;
 
-   patternAnalysis?: any;
 
-   lightingAnalysis?: any;
 
- }
 
- // 新增:增强色彩分析结果接口
 
- export interface EnhancedColorAnalysis {
 
-   colorWheel: ColorWheelData;
 
-   colorHarmony: ColorHarmonyAnalysis;
 
-   colorTemperature: ColorTemperatureAnalysis;
 
-   colorPsychology: ColorPsychologyAnalysis;
 
- }
 
- // 色轮数据
 
- export interface ColorWheelData {
 
-   dominantHue: number; // 主色调角度 (0-360)
 
-   saturationRange: { min: number; max: number }; // 饱和度范围
 
-   brightnessRange: { min: number; max: number }; // 亮度范围
 
-   colorDistribution: Array<{
 
-     hue: number;
 
-     saturation: number;
 
-     brightness: number;
 
-     percentage: number;
 
-   }>;
 
- }
 
- // 色彩和谐度分析
 
- export interface ColorHarmonyAnalysis {
 
-   harmonyType: 'monochromatic' | 'analogous' | 'complementary' | 'triadic' | 'tetradic' | 'split-complementary';
 
-   harmonyScore: number; // 0-100
 
-   suggestions: string[];
 
-   relationships: Array<{
 
-     color1: string;
 
-     color2: string;
 
-     relationship: string;
 
-     strength: number;
 
-   }>;
 
- }
 
- // 色温详细分析
 
- export interface ColorTemperatureAnalysis {
 
-   averageTemperature: number; // 开尔文值
 
-   temperatureRange: { min: number; max: number };
 
-   warmCoolBalance: number; // -100(冷) 到 100(暖)
 
-   temperatureDescription: string;
 
-   lightingRecommendations: string[];
 
- }
 
- // 色彩心理学分析
 
- export interface ColorPsychologyAnalysis {
 
-   mood: string; // 整体情绪
 
-   atmosphere: string; // 氛围描述
 
-   psychologicalEffects: string[];
 
-   suitableSpaces: string[]; // 适合的空间类型
 
-   emotionalImpact: {
 
-     energy: number; // 0-100
 
-     warmth: number; // 0-100
 
-     sophistication: number; // 0-100
 
-     comfort: number; // 0-100
 
-   };
 
- }
 
- export interface AnalysisProgress {
 
-   stage: 'preparing' | 'processing' | 'extracting' | 'generating' | 'completed' | 'error';
 
-   message: string;
 
-   progress: number;
 
- }
 
- @Injectable({
 
-   providedIn: 'root'
 
- })
 
- export class ColorAnalysisService {
 
-   private readonly API_BASE = '/api/color-analysis';
 
-   private analysisProgress$ = new BehaviorSubject<AnalysisProgress>({
 
-     stage: 'preparing',
 
-     message: '准备分析...',
 
-     progress: 0
 
-   });
 
-   constructor(
 
-     private http: HttpClient,
 
-     private formAnalysisService: FormAnalysisService,
 
-     private textureAnalysisService: TextureAnalysisService,
 
-     private patternAnalysisService: PatternAnalysisService,
 
-     private lightingAnalysisService: LightingAnalysisService
 
-   ) {}
 
-   /**
 
-    * 获取分析进度
 
-    */
 
-   getAnalysisProgress(): Observable<AnalysisProgress> {
 
-     return this.analysisProgress$.asObservable();
 
-   }
 
-   /**
 
-    * 分析图片颜色
 
-    * @param imageFile 图片文件
 
-    * @param options 分析选项
 
-    */
 
-   analyzeImageColors(imageFile: File, options?: {
 
-     mosaicSize?: number;
 
-     maxColors?: number;
 
-   }): Observable<ColorAnalysisResult> {
 
-     const formData = new FormData();
 
-     formData.append('image', imageFile);
 
-     
 
-     if (options?.mosaicSize) {
 
-       formData.append('mosaicSize', options.mosaicSize.toString());
 
-     }
 
-     if (options?.maxColors) {
 
-       formData.append('maxColors', options.maxColors.toString());
 
-     }
 
-     return this.http.post<any>(`${this.API_BASE}/analyze`, formData).pipe(
 
-       map((response: any) => {
 
-         if (response && response.success) {
 
-           return this.parseAnalysisResult(response.data);
 
-         }
 
-         throw new Error('分析结果无效');
 
-       }),
 
-       catchError(error => {
 
-         console.error('颜色分析失败:', error);
 
-         return throwError(() => new Error('颜色分析服务暂时不可用'));
 
-       })
 
-     );
 
-   }
 
-   /**
 
-    * 分析上传的图片文件
 
-    * @param file 上传的文件信息
 
-    */
 
-   analyzeImage(file: UploadedFile): Observable<ColorAnalysisResult> {
 
-     // 暂时使用模拟分析,避免API 404错误
 
-     console.log('使用模拟分析处理文件:', file.name);
 
-     
 
-     // 创建一个File对象用于模拟分析
 
-     return new Observable(observer => {
 
-       // 如果有预览URL,尝试获取文件
 
-       if (file.preview || file.url) {
 
-         fetch(file.preview || file.url)
 
-           .then(response => response.blob())
 
-           .then(blob => {
 
-             const mockFile = new File([blob], file.name, { type: file.type || 'image/jpeg' });
 
-             this.simulateAnalysis(mockFile).subscribe({
 
-               next: (result) => observer.next(result),
 
-               error: (error) => observer.error(error),
 
-               complete: () => observer.complete()
 
-             });
 
-           })
 
-           .catch(error => {
 
-             console.warn('无法获取文件内容,使用默认模拟数据:', error);
 
-             // 如果无法获取文件,直接返回模拟结果
 
-             this.getDefaultMockResult(file).subscribe({
 
-               next: (result) => observer.next(result),
 
-               error: (error) => observer.error(error),
 
-               complete: () => observer.complete()
 
-             });
 
-           });
 
-       } else {
 
-         // 没有文件URL,直接返回模拟结果
 
-         this.getDefaultMockResult(file).subscribe({
 
-           next: (result) => observer.next(result),
 
-           error: (error) => observer.error(error),
 
-           complete: () => observer.complete()
 
-         });
 
-       }
 
-     });
 
-   }
 
-   /**
 
-    * 获取默认模拟结果
 
-    */
 
-   private getDefaultMockResult(file: UploadedFile): Observable<ColorAnalysisResult> {
 
-     return new Observable(observer => {
 
-       this.updateProgress('processing', '开始分析...', 10);
 
-       
 
-       setTimeout(() => {
 
-         this.updateProgress('extracting', '提取颜色信息...', 50);
 
-         
 
-         setTimeout(() => {
 
-           this.updateProgress('generating', '生成分析报告...', 80);
 
-           
 
-           setTimeout(() => {
 
-             const mockResult: ColorAnalysisResult = {
 
-               colors: [
 
-                 { hex: '#FF6B6B', rgb: { r: 255, g: 107, b: 107 }, percentage: 25.5, name: '珊瑚红' },
 
-                 { hex: '#4ECDC4', rgb: { r: 78, g: 205, b: 196 }, percentage: 18.3, name: '青绿色' },
 
-                 { hex: '#45B7D1', rgb: { r: 69, g: 183, b: 209 }, percentage: 15.7, name: '天蓝色' },
 
-                 { hex: '#96CEB4', rgb: { r: 150, g: 206, b: 180 }, percentage: 12.1, name: '薄荷绿' },
 
-                 { hex: '#FFEAA7', rgb: { r: 255, g: 234, b: 167 }, percentage: 10.8, name: '柠檬黄' },
 
-                 { hex: '#DDA0DD', rgb: { r: 221, g: 160, b: 221 }, percentage: 8.9, name: '紫罗兰' },
 
-                 { hex: '#98D8C8', rgb: { r: 152, g: 216, b: 200 }, percentage: 8.7, name: '海泡石绿' }
 
-               ],
 
-               originalImage: file.preview || file.url || document.baseURI+'/assets/images/placeholder.jpg',
 
-               mosaicImage: file.preview || file.url || document.baseURI+'/assets/images/placeholder.jpg',
 
-               reportPath: '/mock-report.html',
 
-               enhancedAnalysis: this.performEnhancedColorAnalysis([
 
-                 { hex: '#FF6B6B', rgb: { r: 255, g: 107, b: 107 }, percentage: 25.5 },
 
-                 { hex: '#4ECDC4', rgb: { r: 78, g: 205, b: 196 }, percentage: 18.3 },
 
-                 { hex: '#45B7D1', rgb: { r: 69, g: 183, b: 209 }, percentage: 15.7 },
 
-                 { hex: '#96CEB4', rgb: { r: 150, g: 206, b: 180 }, percentage: 12.1 },
 
-                 { hex: '#FFEAA7', rgb: { r: 255, g: 234, b: 167 }, percentage: 10.8 }
 
-               ])
 
-             };
 
-             this.updateProgress('completed', '分析完成', 100);
 
-             observer.next(mockResult);
 
-             observer.complete();
 
-           }, 300);
 
-         }, 400);
 
-       }, 300);
 
-     });
 
-   }
 
-   /**
 
-    * 获取分析报告
 
-    * @param reportId 报告ID
 
-    */
 
-   getAnalysisReport(reportId: string): Observable<string> {
 
-     return this.http.get(`${this.API_BASE}/report/${reportId}`, {
 
-       responseType: 'text'
 
-     });
 
-   }
 
-   /**
 
-    * 批量分析多个图片
 
-    * @param imageFiles 图片文件数组
 
-    */
 
-   analyzeBatchImages(imageFiles: File[]): Observable<ColorAnalysisResult[]> {
 
-     this.updateProgress('preparing', '准备批量分析...', 0);
 
-     const formData = new FormData();
 
-     imageFiles.forEach((file, index) => {
 
-       formData.append(`images`, file);
 
-     });
 
-     return this.http.post<any>(`${this.API_BASE}/analyze-batch`, formData).pipe(
 
-       map(response => {
 
-         this.updateProgress('completed', '批量分析完成', 100);
 
-         return response.results.map((result: any) => this.parseAnalysisResult(result));
 
-       }),
 
-       catchError(error => {
 
-         this.updateProgress('error', '批量分析失败: ' + (error.message || '未知错误'), 0);
 
-         return throwError(() => error);
 
-       })
 
-     );
 
-   }
 
-   /**
 
-    * 检查color-get服务状态
 
-    */
 
-   checkServiceStatus(): Observable<boolean> {
 
-     return this.http.get<{ status: string }>(`${this.API_BASE}/status`).pipe(
 
-       map(response => response.status === 'ready'),
 
-       catchError(() => throwError(() => new Error('颜色分析服务不可用')))
 
-     );
 
-   }
 
-   /**
 
-    * 增强色彩分析 - 包含色轮、和谐度、色温、心理学分析
 
-    * @param colors 基础颜色分析结果
 
-    */
 
-   performEnhancedColorAnalysis(colors: Array<{hex: string; rgb: {r: number; g: number; b: number}; percentage: number}>): EnhancedColorAnalysis {
 
-     return {
 
-       colorWheel: this.analyzeColorWheel(colors),
 
-       colorHarmony: this.analyzeColorHarmony(colors),
 
-       colorTemperature: this.analyzeColorTemperature(colors),
 
-       colorPsychology: this.analyzeColorPsychology(colors)
 
-     };
 
-   }
 
-   /**
 
-    * 色轮分析
 
-    */
 
-   private analyzeColorWheel(colors: Array<{hex: string; rgb: {r: number; g: number; b: number}; percentage: number}>): ColorWheelData {
 
-     const colorDistribution = colors.map(color => {
 
-       const hsl = this.rgbToHsl(color.rgb.r, color.rgb.g, color.rgb.b);
 
-       return {
 
-         hue: hsl.h,
 
-         saturation: hsl.s,
 
-         brightness: hsl.l,
 
-         percentage: color.percentage
 
-       };
 
-     });
 
-     const dominantColor = colorDistribution.reduce((prev, current) => 
 
-       prev.percentage > current.percentage ? prev : current
 
-     );
 
-     const saturationValues = colorDistribution.map(c => c.saturation);
 
-     const brightnessValues = colorDistribution.map(c => c.brightness);
 
-     return {
 
-       dominantHue: dominantColor.hue,
 
-       saturationRange: {
 
-         min: Math.min(...saturationValues),
 
-         max: Math.max(...saturationValues)
 
-       },
 
-       brightnessRange: {
 
-         min: Math.min(...brightnessValues),
 
-         max: Math.max(...brightnessValues)
 
-       },
 
-       colorDistribution
 
-     };
 
-   }
 
-   /**
 
-    * 色彩和谐度分析
 
-    */
 
-   private analyzeColorHarmony(colors: Array<{hex: string; rgb: {r: number; g: number; b: number}; percentage: number}>): ColorHarmonyAnalysis {
 
-     const hues = colors.map(color => {
 
-       const hsl = this.rgbToHsl(color.rgb.r, color.rgb.g, color.rgb.b);
 
-       return { hue: hsl.h, hex: color.hex, percentage: color.percentage };
 
-     });
 
-     // 分析色彩关系
 
-     const relationships:any = [];
 
-     for (let i = 0; i < hues.length; i++) {
 
-       for (let j = i + 1; j < hues.length; j++) {
 
-         const hueDiff = Math.abs(hues[i].hue - hues[j].hue);
 
-         const minDiff = Math.min(hueDiff, 360 - hueDiff);
 
-         
 
-         let relationship = '';
 
-         let strength = 0;
 
-         
 
-         if (minDiff < 30) {
 
-           relationship = '相似色';
 
-           strength = 90 - minDiff;
 
-         } else if (minDiff > 150 && minDiff < 210) {
 
-           relationship = '互补色';
 
-           strength = 100 - Math.abs(minDiff - 180);
 
-         } else if (minDiff > 110 && minDiff < 130) {
 
-           relationship = '三角色';
 
-           strength = 100 - Math.abs(minDiff - 120);
 
-         }
 
-         if (relationship) {
 
-           relationships.push({
 
-             color1: hues[i].hex,
 
-             color2: hues[j].hex,
 
-             relationship,
 
-             strength
 
-           });
 
-         }
 
-       }
 
-     }
 
-     // 确定和谐类型
 
-     let harmonyType: ColorHarmonyAnalysis['harmonyType'] = 'monochromatic';
 
-     let harmonyScore = 60;
 
-     if (relationships.some(r => r.relationship === '互补色' && r.strength > 80)) {
 
-       harmonyType = 'complementary';
 
-       harmonyScore = 85;
 
-     } else if (relationships.filter(r => r.relationship === '相似色').length >= 2) {
 
-       harmonyType = 'analogous';
 
-       harmonyScore = 75;
 
-     } else if (relationships.some(r => r.relationship === '三角色')) {
 
-       harmonyType = 'triadic';
 
-       harmonyScore = 80;
 
-     }
 
-     return {
 
-       harmonyType,
 
-       harmonyScore,
 
-       relationships,
 
-       suggestions: this.generateHarmonySuggestions(harmonyType, harmonyScore)
 
-     };
 
-   }
 
-   /**
 
-    * 色温分析
 
-    */
 
-   private analyzeColorTemperature(colors: Array<{hex: string; rgb: {r: number; g: number; b: number}; percentage: number}>): ColorTemperatureAnalysis {
 
-     const temperatures = colors.map(color => {
 
-       // 简化的色温计算
 
-       const temp = this.calculateColorTemperature(color.rgb);
 
-       return { temperature: temp, percentage: color.percentage };
 
-     });
 
-     const weightedAverage = temperatures.reduce((sum, t) => sum + t.temperature * t.percentage, 0) / 100;
 
-     const tempValues = temperatures.map(t => t.temperature);
 
-     
 
-     const warmCoolBalance = this.calculateWarmCoolBalance(colors);
 
-     
 
-     return {
 
-       averageTemperature: Math.round(weightedAverage),
 
-       temperatureRange: {
 
-         min: Math.min(...tempValues),
 
-         max: Math.max(...tempValues)
 
-       },
 
-       warmCoolBalance,
 
-       temperatureDescription: this.getTemperatureDescription(weightedAverage),
 
-       lightingRecommendations: this.generateLightingRecommendations(weightedAverage, warmCoolBalance)
 
-     };
 
-   }
 
-   /**
 
-    * 色彩心理学分析
 
-    */
 
-   private analyzeColorPsychology(colors: Array<{hex: string; rgb: {r: number; g: number; b: number}; percentage: number}>): ColorPsychologyAnalysis {
 
-     const psychologyData = colors.map(color => {
 
-       const psychology = this.getColorPsychology(color.hex);
 
-       return { ...psychology, percentage: color.percentage };
 
-     });
 
-     // 计算加权平均情感影响
 
-     const emotionalImpact = {
 
-       energy: Math.round(psychologyData.reduce((sum, p) => sum + p.energy * p.percentage, 0) / 100),
 
-       warmth: Math.round(psychologyData.reduce((sum, p) => sum + p.warmth * p.percentage, 0) / 100),
 
-       sophistication: Math.round(psychologyData.reduce((sum, p) => sum + p.sophistication * p.percentage, 0) / 100),
 
-       comfort: Math.round(psychologyData.reduce((sum, p) => sum + p.comfort * p.percentage, 0) / 100)
 
-     };
 
-     return {
 
-       mood: this.determineMood(emotionalImpact),
 
-       atmosphere: this.determineAtmosphere(emotionalImpact),
 
-       psychologicalEffects: this.aggregatePsychologicalEffects(psychologyData),
 
-       suitableSpaces: this.determineSuitableSpaces(emotionalImpact),
 
-       emotionalImpact
 
-     };
 
-   }
 
-   // 辅助方法
 
-   private rgbToHsl(r: number, g: number, b: number): {h: number, s: number, l: number} {
 
-     r /= 255; g /= 255; b /= 255;
 
-     const max = Math.max(r, g, b), min = Math.min(r, g, b);
 
-     let h = 0, s = 0, l = (max + min) / 2;
 
-     if (max !== min) {
 
-       const d = max - min;
 
-       s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
 
-       switch (max) {
 
-         case r: h = (g - b) / d + (g < b ? 6 : 0); break;
 
-         case g: h = (b - r) / d + 2; break;
 
-         case b: h = (r - g) / d + 4; break;
 
-       }
 
-       h /= 6;
 
-     }
 
-     return { h: h * 360, s: s * 100, l: l * 100 };
 
-   }
 
-   private calculateColorTemperature(rgb: {r: number, g: number, b: number}): number {
 
-     // 简化的色温计算公式
 
-     const ratio = rgb.b / (rgb.r + rgb.g + rgb.b);
 
-     return Math.round(2000 + ratio * 4000); // 2000K-6000K范围
 
-   }
 
-   private calculateWarmCoolBalance(colors: Array<{hex: string; rgb: {r: number; g: number; b: number}; percentage: number}>): number {
 
-     let warmScore = 0;
 
-     colors.forEach(color => {
 
-       const { r, g, b } = color.rgb;
 
-       const warmness = (r - b) / 255 * 100; // 红色减蓝色的比例
 
-       warmScore += warmness * color.percentage / 100;
 
-     });
 
-     return Math.max(-100, Math.min(100, warmScore));
 
-   }
 
-   private getTemperatureDescription(temp: number): string {
 
-     if (temp < 3000) return '暖色调';
 
-     if (temp < 4000) return '中性偏暖';
 
-     if (temp < 5000) return '中性色调';
 
-     if (temp < 6000) return '中性偏冷';
 
-     return '冷色调';
 
-   }
 
-   private generateLightingRecommendations(temp: number, balance: number): string[] {
 
-     const recommendations:any = [];
 
-     if (temp < 3500) {
 
-       recommendations.push('适合使用暖白光照明(2700K-3000K)');
 
-       recommendations.push('营造温馨舒适氛围');
 
-     } else if (temp > 5000) {
 
-       recommendations.push('适合使用冷白光照明(5000K-6500K)');
 
-       recommendations.push('营造清爽现代的感觉');
 
-     } else {
 
-       recommendations.push('适合使用中性白光照明(4000K-4500K)');
 
-       recommendations.push('平衡温暖与清爽的感觉');
 
-     }
 
-     return recommendations;
 
-   }
 
-   private generateHarmonySuggestions(harmonyType: string, score: number): string[] {
 
-     const suggestions:any = [];
 
-     if (score < 70) {
 
-       suggestions.push('考虑调整色彩比例以提高和谐度');
 
-       suggestions.push('可以添加中性色作为过渡');
 
-     }
 
-     
 
-     switch (harmonyType) {
 
-       case 'complementary':
 
-         suggestions.push('互补色搭配,建议一主一辅的比例');
 
-         break;
 
-       case 'analogous':
 
-         suggestions.push('相似色搭配,可以添加少量对比色增加活力');
 
-         break;
 
-       case 'triadic':
 
-         suggestions.push('三角色搭配,注意控制各色彩的饱和度');
 
-         break;
 
-     }
 
-     
 
-     return suggestions;
 
-   }
 
-   private getColorPsychology(hex: string): {energy: number, warmth: number, sophistication: number, comfort: number} {
 
-     // 基于色相的心理学属性(简化版)
 
-     const rgb = this.hexToRgb(hex);
 
-     if (!rgb) return { energy: 50, warmth: 50, sophistication: 50, comfort: 50 };
 
-     
 
-     const hsl = this.rgbToHsl(rgb.r, rgb.g, rgb.b);
 
-     const hue = hsl.h;
 
-     
 
-     // 根据色相确定心理属性
 
-     if (hue >= 0 && hue < 60) { // 红-橙
 
-       return { energy: 85, warmth: 90, sophistication: 60, comfort: 70 };
 
-     } else if (hue >= 60 && hue < 120) { // 黄-绿
 
-       return { energy: 75, warmth: 70, sophistication: 50, comfort: 80 };
 
-     } else if (hue >= 120 && hue < 180) { // 绿-青
 
-       return { energy: 45, warmth: 30, sophistication: 70, comfort: 85 };
 
-     } else if (hue >= 180 && hue < 240) { // 青-蓝
 
-       return { energy: 35, warmth: 20, sophistication: 85, comfort: 75 };
 
-     } else if (hue >= 240 && hue < 300) { // 蓝-紫
 
-       return { energy: 55, warmth: 40, sophistication: 90, comfort: 65 };
 
-     } else { // 紫-红
 
-       return { energy: 70, warmth: 60, sophistication: 80, comfort: 60 };
 
-     }
 
-   }
 
-   private hexToRgb(hex: string): {r: number, g: number, b: number} | null {
 
-     const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
 
-     return result ? {
 
-       r: parseInt(result[1], 16),
 
-       g: parseInt(result[2], 16),
 
-       b: parseInt(result[3], 16)
 
-     } : null;
 
-   }
 
-   private determineMood(impact: {energy: number, warmth: number, sophistication: number, comfort: number}): string {
 
-     if (impact.energy > 70 && impact.warmth > 70) return '活力温暖';
 
-     if (impact.sophistication > 80) return '优雅精致';
 
-     if (impact.comfort > 80) return '舒适宁静';
 
-     if (impact.energy > 70) return '充满活力';
 
-     return '平和稳定';
 
-   }
 
-   private determineAtmosphere(impact: {energy: number, warmth: number, sophistication: number, comfort: number}): string {
 
-     if (impact.warmth > 70 && impact.comfort > 70) return '温馨舒适的家居氛围';
 
-     if (impact.sophistication > 80 && impact.energy < 50) return '高雅静谧的商务氛围';
 
-     if (impact.energy > 70) return '活跃动感的现代氛围';
 
-     return '平衡和谐的中性氛围';
 
-   }
 
-   private aggregatePsychologicalEffects(data: any[]): string[] {
 
-     const effects = new Set<string>();
 
-     data.forEach(d => {
 
-       if (d.energy > 70) effects.add('提升活力和注意力');
 
-       if (d.warmth > 70) effects.add('营造温暖亲切感');
 
-       if (d.sophistication > 80) effects.add('增强空间品质感');
 
-       if (d.comfort > 80) effects.add('促进放松和舒适感');
 
-     });
 
-     return Array.from(effects);
 
-   }
 
-   private determineSuitableSpaces(impact: {energy: number, warmth: number, sophistication: number, comfort: number}): string[] {
 
-     const spaces:any = [];
 
-     if (impact.warmth > 70 && impact.comfort > 70) {
 
-       spaces.push('客厅', '卧室', '餐厅');
 
-     }
 
-     if (impact.sophistication > 80) {
 
-       spaces.push('办公室', '会议室', '接待区');
 
-     }
 
-     if (impact.energy > 70) {
 
-       spaces.push('工作区', '健身房', '娱乐区');
 
-     }
 
-     if (impact.comfort > 80 && impact.energy < 50) {
 
-       spaces.push('休息区', '阅读角', '冥想室');
 
-     }
 
-     return spaces.length > 0 ? spaces : ['通用空间'];
 
-   }
 
-   /**
 
-    * 更新分析进度
 
-    */
 
-   private updateProgress(stage: AnalysisProgress['stage'], message: string, progress: number): void {
 
-     this.analysisProgress$.next({ stage, message, progress });
 
-   }
 
-   /**
 
-    * 解析分析结果
 
-    */
 
-   private parseAnalysisResult(data: any): ColorAnalysisResult {
 
-     return {
 
-       colors: data.colors || [],
 
-       originalImage: data.originalImage || '',
 
-       mosaicImage: data.mosaicImage || '',
 
-       reportPath: data.reportPath || ''
 
-     };
 
-   }
 
-   /**
 
-    * 模拟color-get分析过程(用于开发测试)
 
-    */
 
-   simulateAnalysis(imageFile: File): Observable<ColorAnalysisResult> {
 
-     return new Observable(observer => {
 
-       this.updateProgress('processing', '开始分析...', 10);
 
-       
 
-       setTimeout(() => {
 
-         this.updateProgress('extracting', '提取颜色信息...', 30);
 
-         
 
-         setTimeout(() => {
 
-           this.updateProgress('generating', '生成分析报告...', 70);
 
-           
 
-           // 使用forkJoin来并行处理所有分析服务,添加错误处理
 
-           const analysisObservables = {
 
-             formAnalysis: this.formAnalysisService.analyzeImageForm(imageFile).pipe(
 
-               catchError(error => {
 
-                 console.warn('形体分析失败,使用默认值:', error);
 
-                 return of(null);
 
-               })
 
-             ),
 
-             textureAnalysis: this.textureAnalysisService.analyzeImageTexture(imageFile).pipe(
 
-               catchError(error => {
 
-                 console.warn('质感分析失败,使用默认值:', error);
 
-                 return of(null);
 
-               })
 
-             ),
 
-             patternAnalysis: this.patternAnalysisService.analyzeImagePattern(imageFile).pipe(
 
-               catchError(error => {
 
-                 console.warn('纹理分析失败,使用默认值:', error);
 
-                 return of(null);
 
-               })
 
-             ),
 
-             lightingAnalysis: this.lightingAnalysisService.analyzeImageLighting(imageFile).pipe(
 
-               catchError(error => {
 
-                 console.warn('灯光分析失败,使用默认值:', error);
 
-                 return of(null);
 
-               })
 
-             )
 
-           };
 
-           forkJoin(analysisObservables).subscribe({
 
-             next: (analysisResults) => {
 
-               const mockResult: ColorAnalysisResult = {
 
-                 colors: [
 
-                   { hex: '#FF6B6B', rgb: { r: 255, g: 107, b: 107 }, percentage: 25.5 },
 
-                   { hex: '#4ECDC4', rgb: { r: 78, g: 205, b: 196 }, percentage: 18.3 },
 
-                   { hex: '#45B7D1', rgb: { r: 69, g: 183, b: 209 }, percentage: 15.7 },
 
-                   { hex: '#96CEB4', rgb: { r: 150, g: 206, b: 180 }, percentage: 12.1 },
 
-                   { hex: '#FFEAA7', rgb: { r: 255, g: 234, b: 167 }, percentage: 10.8 },
 
-                   { hex: '#DDA0DD', rgb: { r: 221, g: 160, b: 221 }, percentage: 8.9 },
 
-                   { hex: '#98D8C8', rgb: { r: 152, g: 216, b: 200 }, percentage: 8.7 }
 
-                 ],
 
-                 originalImage: URL.createObjectURL(imageFile),
 
-                 mosaicImage: URL.createObjectURL(imageFile), // 在实际应用中这里应该是处理后的图片
 
-                 reportPath: '/mock-report.html',
 
-                 // 添加增强色彩分析
 
-                 enhancedAnalysis: this.performEnhancedColorAnalysis([
 
-                   { hex: '#FF6B6B', rgb: { r: 255, g: 107, b: 107 }, percentage: 25.5 },
 
-                   { hex: '#4ECDC4', rgb: { r: 78, g: 205, b: 196 }, percentage: 18.3 },
 
-                   { hex: '#45B7D1', rgb: { r: 69, g: 183, b: 209 }, percentage: 15.7 },
 
-                   { hex: '#96CEB4', rgb: { r: 150, g: 206, b: 180 }, percentage: 12.1 },
 
-                   { hex: '#FFEAA7', rgb: { r: 255, g: 234, b: 167 }, percentage: 10.8 }
 
-                 ]),
 
-                 // 添加其他分析结果,如果分析失败则使用默认值
 
-                 formAnalysis: analysisResults.formAnalysis || this.getDefaultFormAnalysis(),
 
-                 textureAnalysis: analysisResults.textureAnalysis || this.getDefaultTextureAnalysis(),
 
-                 patternAnalysis: analysisResults.patternAnalysis || this.getDefaultPatternAnalysis(),
 
-                 lightingAnalysis: analysisResults.lightingAnalysis || this.getDefaultLightingAnalysis()
 
-               };
 
-               this.updateProgress('completed', '分析完成', 100);
 
-               observer.next(mockResult);
 
-               observer.complete();
 
-             },
 
-             error: (error) => {
 
-               console.error('分析服务出错:', error);
 
-               // 即使分析服务出错,也返回基本的颜色分析结果
 
-               const fallbackResult: ColorAnalysisResult = {
 
-                 colors: [
 
-                   { hex: '#FF6B6B', rgb: { r: 255, g: 107, b: 107 }, percentage: 25.5, name: '珊瑚红' },
 
-                   { hex: '#4ECDC4', rgb: { r: 78, g: 205, b: 196 }, percentage: 18.3, name: '青绿色' },
 
-                   { hex: '#45B7D1', rgb: { r: 69, g: 183, b: 209 }, percentage: 15.7, name: '天蓝色' }
 
-                 ],
 
-                 originalImage: URL.createObjectURL(imageFile),
 
-                 mosaicImage: URL.createObjectURL(imageFile),
 
-                 reportPath: '/mock-report.html',
 
-                 enhancedAnalysis: this.performEnhancedColorAnalysis([
 
-                   { hex: '#FF6B6B', rgb: { r: 255, g: 107, b: 107 }, percentage: 25.5 },
 
-                   { hex: '#4ECDC4', rgb: { r: 78, g: 205, b: 196 }, percentage: 18.3 },
 
-                   { hex: '#45B7D1', rgb: { r: 69, g: 183, b: 209 }, percentage: 15.7 }
 
-                 ]),
 
-                 formAnalysis: this.getDefaultFormAnalysis(),
 
-                 textureAnalysis: this.getDefaultTextureAnalysis(),
 
-                 patternAnalysis: this.getDefaultPatternAnalysis(),
 
-                 lightingAnalysis: this.getDefaultLightingAnalysis()
 
-               };
 
-               
 
-               this.updateProgress('completed', '分析完成(部分功能降级)', 100);
 
-               observer.next(fallbackResult);
 
-               observer.complete();
 
-             }
 
-           });
 
-         }, 500);
 
-       }, 300);
 
-     });
 
-   }
 
-   /**
 
-    * 获取默认形体分析结果
 
-    */
 
-   private getDefaultFormAnalysis(): any {
 
-     return {
 
-       spaceAnalysis: {
 
-         spaceType: '现代简约'
 
-       },
 
-       lineAnalysis: {
 
-         dominantLineType: 'straight',
 
-         lineDirection: { horizontal: 60, vertical: 30, diagonal: 10 }
 
-       }
 
-     };
 
-   }
 
-   /**
 
-    * 获取默认质感分析结果
 
-    */
 
-   private getDefaultTextureAnalysis(): any {
 
-     return {
 
-       materialClassification: {
 
-         primary: '光滑表面'
 
-       },
 
-       surfaceProperties: {
 
-         roughness: { level: 'smooth', value: 30 },
 
-         glossiness: { level: 'satin', value: 50 }
 
-       }
 
-     };
 
-   }
 
-   /**
 
-    * 获取默认纹理分析结果
 
-    */
 
-   private getDefaultPatternAnalysis(): any {
 
-     return {
 
-       patternRecognition: {
 
-         primaryPatterns: [
 
-           { type: 'geometric', confidence: 70, coverage: 40 }
 
-         ],
 
-         patternComplexity: { level: 'moderate', score: 50 }
 
-       }
 
-     };
 
-   }
 
-   /**
 
-    * 获取默认灯光分析结果
 
-    */
 
-   private getDefaultLightingAnalysis(): any {
 
-     return {
 
-       ambientAnalysis: {
 
-         lightingMood: '温馨舒适'
 
-       },
 
-       illuminationAnalysis: {
 
-         brightness: { overall: 70 },
 
-         colorTemperature: { kelvin: 3000, warmth: 'warm' }
 
-       }
 
-     };
 
-   }
 
- }
 
 
  |