Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.

Commit 5c2dfc1

Browse files
refactor: migrate logo generation from JSON-to-SVG to direct SVG output for improved quality
1 parent e526569 commit 5c2dfc1

4 files changed

Lines changed: 170 additions & 148 deletions

File tree

api/services/BandIdentity/branding.service.ts

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -597,8 +597,8 @@ export class BrandingService extends GenericService {
597597
}
598598

599599
/**
600-
* Generate single logo concept using optimized JSON-to-SVG approach
601-
* Implements token-saving strategy with compact JSON generation
600+
* Generate single logo concept using direct SVG generation
601+
* AI generates complete SVG content directly for professional results
602602
*/
603603
private async generateSingleLogoConcept(
604604
projectDescription: string,
@@ -608,45 +608,45 @@ export class BrandingService extends GenericService {
608608
conceptIndex: number
609609
): Promise<LogoModel> {
610610
logger.info(
611-
`Generating optimized logo concept ${
611+
`Generating professional logo concept ${
612612
conceptIndex + 1
613-
} using JSON-to-SVG conversion`
613+
} with direct SVG generation`
614614
);
615615

616-
// Build optimized prompt for compact JSON generation
616+
// Build optimized prompt for direct SVG generation
617617
const optimizedPrompt = this.buildOptimizedLogoPrompt(
618618
projectDescription,
619619
colors,
620620
typography
621621
);
622622

623-
// AI generation with max_output_tokens limit for efficiency
623+
// AI generation with direct SVG output
624624
const steps: IPromptStep[] = [
625625
{
626626
promptConstant: optimizedPrompt,
627627
stepName: `Logo Concept ${conceptIndex + 1}`,
628-
maxOutputTokens: 3000,
628+
maxOutputTokens: 4000,
629629
modelParser: (content) => {
630630
try {
631-
// Parse compact JSON logo structure
632-
const logoJson: LogoJsonStructure = JSON.parse(content);
631+
// Parse JSON response containing SVG
632+
const logoData = JSON.parse(content);
633633

634634
// Ensure unique ID for each concept
635-
if (!logoJson.id) {
636-
logoJson.id = `concept${String(conceptIndex + 1).padStart(
635+
if (!logoData.id) {
636+
logoData.id = `concept${String(conceptIndex + 1).padStart(
637637
2,
638638
"0"
639639
)}`;
640640
}
641641

642-
return logoJson;
642+
return logoData;
643643
} catch (error) {
644644
logger.error(
645-
`Error parsing logo JSON concept ${conceptIndex + 1}:`,
645+
`Error parsing logo data concept ${conceptIndex + 1}:`,
646646
error
647647
);
648648
throw new Error(
649-
`Failed to parse logo JSON concept ${conceptIndex + 1}`
649+
`Failed to parse logo data concept ${conceptIndex + 1}`
650650
);
651651
}
652652
},
@@ -658,33 +658,58 @@ export class BrandingService extends GenericService {
658658
provider: LLMProvider.GEMINI,
659659
modelName: "gemini-2.5-flash",
660660
llmOptions: {
661-
maxOutputTokens: 3000,
661+
maxOutputTokens: 4000,
662662
temperature: 0.2,
663663
topP: 0.8,
664664
topK: 20,
665665
},
666666
});
667667
const logoResult = sectionResults[0];
668-
const logoJsonStructure: LogoJsonStructure = logoResult.parsedData;
669-
670-
// Convert JSON structure to optimized SVG LogoModel
671-
const logoModel =
672-
this.logoJsonToSvgService.convertJsonToLogoModel(logoJsonStructure);
673-
674-
// Force unique ID to ensure each concept has a different ID
675-
logoModel.id = `concept${String(conceptIndex + 1).padStart(2, "0")}`;
668+
const logoData = logoResult.parsedData;
669+
670+
// Create LogoModel directly from SVG data
671+
const logoModel: LogoModel = {
672+
id: `concept${String(conceptIndex + 1).padStart(2, "0")}`,
673+
name: logoData.name || `Logo Concept ${conceptIndex + 1}`,
674+
concept: logoData.concept || "Professional logo design",
675+
colors: logoData.colors || [],
676+
fonts: logoData.fonts || [],
677+
svg: logoData.svg, // Direct SVG from AI
678+
iconSvg: this.extractIconFromSvg(logoData.svg), // Extract icon part
679+
};
676680

677681
// Apply SVG optimization
678682
const optimizedLogo = this.optimizeLogoSvgs(logoModel);
679683

680684
logger.info(
681-
`Optimized logo concept ${conceptIndex + 1} generated with ${
682-
logoJsonStructure.icon.shapes.length
683-
} icon shapes and ${logoJsonStructure.text.elements.length} text elements`
685+
`Professional logo concept ${conceptIndex + 1} generated with direct SVG content`
684686
);
685687
return optimizedLogo;
686688
}
687689

690+
/**
691+
* Extract icon-only SVG from the complete logo SVG
692+
* Removes text elements to create an icon-only version
693+
*/
694+
private extractIconFromSvg(fullSvg: string): string {
695+
try {
696+
// Extract the icon group from the full SVG (using multiline regex)
697+
const iconMatch = fullSvg.match(/<g id="icon"[^>]*>([\s\S]*?)<\/g>/);
698+
if (iconMatch) {
699+
// Create a new SVG with just the icon content
700+
const iconContent = iconMatch[1];
701+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80" width="80" height="80"><g id="icon">${iconContent}</g></svg>`;
702+
}
703+
704+
// Fallback: return a simplified version of the full SVG
705+
logger.warn("Could not extract icon from SVG, using fallback");
706+
return fullSvg.replace(/<g id="text"[^>]*>[\s\S]*?<\/g>/, '');
707+
} catch (error) {
708+
logger.error("Error extracting icon from SVG:", error);
709+
return fullSvg; // Return original if extraction fails
710+
}
711+
}
712+
688713
/**
689714
* Optimize logo SVGs using advanced compression techniques
690715
*/
Lines changed: 46 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,62 @@
11
export const LOGO_GENERATION_PROMPT = `
2-
Generate 1 premium, ORIGINAL tech logo concept with sophisticated, professional design. Create a distinctive brand identity that stands out in the market. Return JSON only:
2+
Generate 1 premium, ORIGINAL tech logo concept with sophisticated, professional design. Create a distinctive brand identity that stands out in the market. Return JSON with complete SVG content:
33
44
{
55
"id": "concept01",
66
"name": "Creative Professional Logo Name",
77
"concept": "Detailed, compelling concept description explaining the design philosophy, symbolism, and brand values represented (40-60 words)",
88
"colors": ["#HEX1", "#HEX2", "#HEX3", "#HEX4"],
99
"fonts": ["Modern Professional FontName"],
10-
"icon": {
11-
"shapes": [
12-
{"type": "path", "d": "M20,8 Q35,2 50,8 Q58,25 50,42 Q35,48 20,42 Q12,25 20,8 Z", "fill": "#HEX1"},
13-
{"type": "circle", "cx": 35, "cy": 25, "r": 12, "fill": "#HEX2", "opacity": 0.85},
14-
{"type": "polygon", "points": "28,18 42,18 40,32 30,32", "fill": "#HEX3"},
15-
{"type": "path", "d": "M25,15 L45,15 L42,35 L28,35 Z", "fill": "#HEX4", "opacity": 0.7}
16-
],
17-
"size": {"w": 70, "h": 50}
18-
},
19-
"text": {
20-
"elements": [
21-
{"type": "text", "x": 0, "y": 28, "text": "BRAND", "fontSize": 24, "fill": "#HEX1", "fontFamily": "FontName", "fontWeight": "700"}
22-
],
23-
"size": {"w": 120, "h": 32}
24-
},
10+
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 200 80\" width=\"200\" height=\"80\"><defs><style>.text-font{font-family:'Inter',Arial,sans-serif;font-weight:700;}</style></defs><g id=\"icon\"><path d=\"M20,8 Q35,2 50,8 Q58,25 50,42 Q35,48 20,42 Q12,25 20,8 Z\" fill=\"#HEX1\"/><circle cx=\"35\" cy=\"25\" r=\"12\" fill=\"#HEX2\" opacity=\"0.85\"/><polygon points=\"28,18 42,18 40,32 30,32\" fill=\"#HEX3\"/><path d=\"M25,15 L45,15 L42,35 L28,35 Z\" fill=\"#HEX4\" opacity=\"0.7\"/></g><g id=\"text\"><text x=\"78\" y=\"45\" class=\"text-font\" font-size=\"24\" fill=\"#HEX1\">BRAND</text></g></svg>",
2511
"layout": {
2612
"textPosition": "right",
27-
"spacing": 8
13+
"spacing": 8,
14+
"totalWidth": 200,
15+
"totalHeight": 80
2816
}
2917
}
3018
31-
DESIGN EXCELLENCE REQUIREMENTS:
32-
- DESCRIPTIONS MUST BE DETAILED AND COMPELLING: 40-60 words explaining design philosophy, symbolism, and brand values
33-
- CREATE UNIQUE, MEMORABLE, PROFESSIONAL DESIGNS - avoid basic circles/rectangles
34-
- Use sophisticated shapes: complex paths with curves, advanced polygons, overlapping elements
35-
- Combine 3-5 shapes with different opacities (0.6-1.0) for depth and visual richness
36-
- Create strong visual hierarchy with size variation, layering, and strategic positioning
37-
- Use premium color palettes with 3-4 complementary colors for sophisticated gradients
38-
- Implement golden ratio proportions and advanced geometric principles
39-
- Add intricate geometric patterns, intersections, and visual effects
40-
- Master negative space as a powerful design element
41-
- Ensure shapes are precisely positioned with professional alignment and balance
42-
- Create cohesive, premium color harmony that conveys brand sophistication
43-
- Design should be scalable and work across all media formats
44-
- Include subtle details that enhance professionalism without cluttering
19+
SVG GENERATION REQUIREMENTS:
20+
- GENERATE COMPLETE, PROFESSIONAL SVG CODE with proper XML structure
21+
- Use viewBox="0 0 200 80" for consistent scaling and professional proportions
22+
- Include proper xmlns="http://www.w3.org/2000/svg" declaration
23+
- Create sophisticated icon designs using advanced SVG elements:
24+
* Complex <path> elements with Bézier curves for organic shapes
25+
* Strategic <circle>, <ellipse>, <polygon> for geometric precision
26+
* Advanced <g> grouping for logical organization
27+
* Proper opacity and layering for depth and visual richness
28+
- Position icon elements in the left portion (0-70px width)
29+
- Position text elements starting around x="78" for proper spacing
30+
- Use professional typography with Inter font family and fallbacks
31+
- Include CSS styles in <defs><style> for consistent formatting
32+
- Ensure text is properly aligned and sized (font-size: 24px minimum)
33+
- Create 3-5 sophisticated shapes with varying opacities (0.6-1.0)
34+
- Use premium color palettes with 3-4 complementary hex colors
35+
- Implement proper spacing between icon and text (8px minimum)
36+
- Ensure scalable design that works at any size
37+
- Add subtle gradients or effects using SVG <defs> when appropriate
4538
46-
TECHNICAL PRECISION:
47-
- Path elements for organic/curved shapes (use advanced quadratic/cubic Bézier curves)
48-
- Complex polygons for angular/geometric elements with precise point positioning
49-
- Strategic use of opacity (0.6-1.0) and advanced layering techniques
50-
- Pixel-perfect coordinate positioning for professional alignment
51-
- Icon dimensions: MINIMUM 70x50px for better visibility and detail
52-
- Text positioning relative to container (0,0 origin) with professional spacing
53-
- Smart layout choice: text width > icon width → "bottom", else → "right"
54-
- Calculate text width: ~12px per character + padding for larger fonts
55-
- Text height: fontSize * 1.4 for proper spacing and readability
56-
- Spacing: 8-12px for optimal separation and professional appearance
57-
- Font size: MINIMUM 24px for better readability and professional impact
58-
- Use font weights 600-700 for strong brand presence
59-
- Ensure all elements are scalable and maintain quality at different sizes
39+
LAYOUT INTELLIGENCE:
40+
- Analyze text length vs icon complexity to choose optimal layout
41+
- For long brand names (>8 characters): consider vertical "bottom" layout
42+
- For short names (≤8 characters): use horizontal "right" layout
43+
- Adjust viewBox dimensions accordingly: horizontal=200x80, vertical=120x120
44+
- Ensure no overlapping between icon and text elements
45+
- Maintain professional spacing and visual balance
6046
61-
AVOID: Basic shapes only, poor positioning, generic designs, overlapping text, small dimensions, weak typography
62-
GOAL: Create distinctive, premium, professional logos that command attention, convey brand authority, and stand out in competitive markets. Each logo should be a masterpiece of design that clients would be proud to use across all their brand materials.
47+
SVG STRUCTURE EXAMPLE:
48+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 80" width="200" height="80">
49+
<defs>
50+
<style>.text-font{font-family:'Inter',Arial,sans-serif;font-weight:700;}</style>
51+
</defs>
52+
<g id="icon">
53+
<!-- Sophisticated icon shapes here -->
54+
</g>
55+
<g id="text">
56+
<text x="78" y="45" class="text-font" font-size="24" fill="#COLOR">BRAND</text>
57+
</g>
58+
</svg>
59+
60+
AVOID: Broken XML, missing namespaces, overlapping elements, poor spacing, basic shapes only
61+
GOAL: Generate production-ready SVG logos that are immediately usable, professionally designed, and scalable across all media formats.
6362
`;
Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,48 @@
11
export const LOGO_VARIATIONS_GENERATION_PROMPT = `
2-
Generate 3 professional icon variations from the provided logo structure with enhanced dimensions and quality. Use the ORIGINAL COLORS from the logo and adapt them appropriately for each background. Return JSON only:
2+
Generate 3 professional icon variations from the provided logo with complete SVG code. Extract ONLY the icon part (no text) and adapt colors for each background. Return JSON with complete SVG content:
33
44
{
55
"variations": {
6-
"lightBackground": {
7-
"shapes": [
8-
{"type": "circle", "cx": 35, "cy": 35, "r": 25, "fill": "#2563EB"}
9-
],
10-
"size": {"w": 70, "h": 70}
11-
},
12-
"darkBackground": {
13-
"shapes": [
14-
{"type": "circle", "cx": 35, "cy": 35, "r": 25, "fill": "#60A5FA"}
15-
],
16-
"size": {"w": 70, "h": 70}
17-
},
18-
"monochrome": {
19-
"shapes": [
20-
{"type": "circle", "cx": 35, "cy": 35, "r": 25, "fill": "#1F2937"}
21-
],
22-
"size": {"w": 70, "h": 70}
23-
}
6+
"lightBackground": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 80 80\" width=\"80\" height=\"80\"><g id=\"icon\"><circle cx=\"40\" cy=\"40\" r=\"30\" fill=\"#2563EB\"/></g></svg>",
7+
"darkBackground": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 80 80\" width=\"80\" height=\"80\"><g id=\"icon\"><circle cx=\"40\" cy=\"40\" r=\"30\" fill=\"#60A5FA\"/></g></svg>",
8+
"monochrome": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 80 80\" width=\"80\" height=\"80\"><g id=\"icon\"><circle cx=\"40\" cy=\"40\" r=\"30\" fill=\"#374151\"/></g></svg>"
249
}
2510
}
2611
27-
PROFESSIONAL VARIATION RULES:
28-
- Extract and enhance icon shapes only, remove all text elements
29-
- MINIMUM dimensions: 70x70px for professional quality and visibility
12+
SVG VARIATION GENERATION RULES:
13+
- GENERATE COMPLETE SVG CODE for each variation with proper XML structure
14+
- Extract ONLY the icon elements from the original logo (remove all text)
15+
- Use viewBox="0 0 80 80" for square icon format (80x80px minimum)
16+
- Include proper xmlns="http://www.w3.org/2000/svg" declaration
3017
- Maintain all original shape complexity and sophistication
3118
- Preserve geometric relationships and proportional scaling
32-
- USE THE ORIGINAL LOGO COLORS as base, then adapt them for each variation:
19+
- Center the icon within the 80x80 viewBox for optimal presentation
3320
3421
COLOR ADAPTATION STRATEGY:
35-
- lightBackground: Use the original colors but ensure good contrast (darken if needed: -20% to -40% brightness)
36-
- darkBackground: Use lighter versions of original colors (+30% to +50% brightness) or complementary light tones
37-
- monochrome: Convert the dominant original color to a sophisticated monochrome version (preserve hue but desaturate)
22+
- lightBackground: Use darker versions of original colors for good contrast
23+
* Reduce brightness by 20-40% from original colors
24+
* Ensure WCAG AA contrast compliance on light backgrounds
25+
- darkBackground: Use lighter, more vibrant versions of original colors
26+
* Increase brightness by 30-50% from original colors
27+
* Add slight saturation boost for better visibility on dark backgrounds
28+
- monochrome: Convert to sophisticated grayscale maintaining visual hierarchy
29+
* Use professional gray palette: #111827, #374151, #4B5563, #6B7280
30+
* Preserve opacity relationships for depth and layering
31+
32+
SVG STRUCTURE REQUIREMENTS:
33+
- Proper XML declaration and namespace
34+
- Clean <g id="icon"> grouping for organization
35+
- Maintain all original path complexity and Bézier curves
36+
- Preserve opacity values (0.6-1.0) for depth and visual richness
37+
- Scale coordinates proportionally to fit 80x80 viewBox
38+
- Center icon elements around cx="40" cy="40" reference point
39+
- Ensure scalable design that works at any size
3840
3941
COLOR EXAMPLES:
40-
- If original is #3B82F6 (blue): lightBackground=#1D4ED8, darkBackground=#60A5FA, monochrome=#374151
41-
- If original is #10B981 (green): lightBackground=#047857, darkBackground=#34D399, monochrome=#4B5563
42-
- If original is #F59E0B (orange): lightBackground=#D97706, darkBackground=#FCD34D, monochrome=#6B7280
42+
- Original #3B82F6 (blue): light=#1D4ED8, dark=#60A5FA, mono=#374151
43+
- Original #10B981 (green): light=#047857, dark=#34D399, mono=#4B5563
44+
- Original #F59E0B (orange): light=#D97706, dark=#FCD34D, mono=#6B7280
4345
44-
- Maximum 8 shapes per variation to maintain detail and complexity
45-
- Scale all coordinates proportionally to larger dimensions
46-
- Ensure all opacity values are preserved for depth and layering
47-
- Maintain professional alignment and spacing
48-
- NEVER use pure black (#000000) or pure white (#FFFFFF) unless original logo uses them
49-
- Single line JSON, no explanations or additional text
46+
AVOID: Broken XML, missing namespaces, text elements, poor centering, basic shapes only
47+
GOAL: Generate production-ready icon SVGs that are immediately usable across light/dark themes and monochrome applications.
5048
`;

0 commit comments

Comments
 (0)