Lcmind commited on
Commit
fc244a5
·
1 Parent(s): 249d349

fix: S-tier prompt - hex to color name, blur UI text, remove watermarks

Browse files
Files changed (1) hide show
  1. app/services/flux.py +70 -19
app/services/flux.py CHANGED
@@ -6,6 +6,58 @@ import io
6
  from app.core.config import settings
7
 
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  async def generate_poster(analysis: dict) -> str:
10
  """
11
  Generate a poster using Flux.1-schnell based on analysis.
@@ -22,34 +74,34 @@ async def generate_poster(analysis: dict) -> str:
22
  """
23
  # Extract analysis data
24
  brand_name = analysis.get('brand_name', 'BRAND').upper()
25
- business_type = analysis.get('business_type', 'Productivity')
26
  poster_objects = analysis.get('poster_objects', 'modern workspace elements')
27
  background_style = analysis.get('background_style', 'Clean gradient')
28
  primary_color = analysis.get('primary_color', '#4A90D9')
29
  mood = analysis.get('mood', 'Clean')
30
 
31
- # === PROMPT MASTER'S TEXT GENERATION RULES FOR FLUX ===
 
 
 
32
  #
33
- # Rule 1: Quote the text exactly - Flux reads quoted strings
34
- # Rule 2: Specify font style and weight (bold, sans-serif, etc.)
35
- # Rule 3: Specify exact position (top center, bottom left, etc.)
36
- # Rule 4: Make text part of the design context (signage, neon, embossed)
37
- # Rule 5: Keep text SHORT (1-2 words max for reliability)
38
 
39
- prompt = f"""High-end commercial poster design, vertical 9:16 format.
40
-
41
- Typography: Bold modern text "{brand_name}" prominently displayed at top center of the frame, clean sans-serif font, white text with subtle shadow, professional branding typography.
42
 
43
- Scene: {poster_objects} arranged beautifully below the text, {background_style} setting, {mood.lower()} atmosphere.
44
 
45
- Color palette: {primary_color} as accent color, harmonious tones throughout.
46
 
47
- Style: Premium advertising campaign aesthetic, Apple-style minimalism, magazine cover quality, professional product photography.
48
 
49
- Technical: Studio lighting, soft shadows, sharp focus, 8k resolution, commercial photography, masterpiece."""
50
 
51
- # Negative prompt - allow text but block unwanted elements
52
- negative_prompt = "blurry, noise, grainy, amateur, low quality, distorted, ugly, planets, space, galaxy, stars, cosmos, abstract art, random patterns, cluttered, messy, chaotic, bad typography, misspelled text, distorted letters, unreadable text"
53
 
54
  headers = {
55
  "Authorization": f"Bearer {settings.hf_token}",
@@ -61,15 +113,14 @@ Technical: Studio lighting, soft shadows, sharp focus, 8k resolution, commercial
61
  "inputs": prompt,
62
  "parameters": {
63
  "negative_prompt": negative_prompt,
64
- "num_inference_steps": 4, # Schnell is optimized for 4 steps
65
- "guidance_scale": 0.0, # Schnell uses guidance_scale 0
66
  "width": 768,
67
  "height": 1344,
68
  }
69
  }
70
 
71
  async with httpx.AsyncClient(timeout=60.0) as client:
72
- # Use new HF Router endpoint
73
  response = await client.post(
74
  f"https://router.huggingface.co/hf-inference/models/{settings.flux_model}",
75
  headers=headers,
 
6
  from app.core.config import settings
7
 
8
 
9
+ def hex_to_color_name(hex_color: str) -> str:
10
+ """Convert hex color to descriptive color name to prevent hex appearing in image."""
11
+ hex_color = hex_color.upper().replace('#', '')
12
+
13
+ # Common brand colors mapping
14
+ color_map = {
15
+ '4285F4': 'vibrant blue', # Google Blue
16
+ 'DB4437': 'warm red', # Google Red
17
+ 'F4B400': 'golden yellow', # Google Yellow
18
+ '0F9D58': 'fresh green', # Google Green
19
+ '1877F2': 'facebook blue',
20
+ 'FF0000': 'bold red', # YouTube
21
+ '000000': 'deep black',
22
+ 'FFFFFF': 'pure white',
23
+ '4A90D9': 'sky blue',
24
+ 'FF6B6B': 'coral pink',
25
+ '6C5CE7': 'electric purple',
26
+ '00D4AA': 'mint green',
27
+ 'FFD93D': 'sunny yellow',
28
+ }
29
+
30
+ if hex_color in color_map:
31
+ return color_map[hex_color]
32
+
33
+ # Parse RGB and describe
34
+ try:
35
+ r = int(hex_color[0:2], 16)
36
+ g = int(hex_color[2:4], 16)
37
+ b = int(hex_color[4:6], 16)
38
+
39
+ # Determine dominant color
40
+ if r > g and r > b:
41
+ if r > 200: return 'bright red tones'
42
+ return 'warm red tones'
43
+ elif g > r and g > b:
44
+ if g > 200: return 'vibrant green tones'
45
+ return 'fresh green tones'
46
+ elif b > r and b > g:
47
+ if b > 200: return 'bright blue tones'
48
+ return 'cool blue tones'
49
+ elif r > 200 and g > 200:
50
+ return 'warm golden tones'
51
+ elif r > 200 and b > 200:
52
+ return 'magenta pink tones'
53
+ elif g > 200 and b > 200:
54
+ return 'cyan aqua tones'
55
+ else:
56
+ return 'neutral tones'
57
+ except:
58
+ return 'harmonious tones'
59
+
60
+
61
  async def generate_poster(analysis: dict) -> str:
62
  """
63
  Generate a poster using Flux.1-schnell based on analysis.
 
74
  """
75
  # Extract analysis data
76
  brand_name = analysis.get('brand_name', 'BRAND').upper()
 
77
  poster_objects = analysis.get('poster_objects', 'modern workspace elements')
78
  background_style = analysis.get('background_style', 'Clean gradient')
79
  primary_color = analysis.get('primary_color', '#4A90D9')
80
  mood = analysis.get('mood', 'Clean')
81
 
82
+ # Convert hex to color name (prevents hex code appearing in image)
83
+ color_description = hex_to_color_name(primary_color)
84
+
85
+ # === S-TIER PROMPT ENGINEER RULES ===
86
  #
87
+ # Rule 1: ONLY the brand name as readable text
88
+ # Rule 2: All other UI elements = blurred/abstract/no text
89
+ # Rule 3: Color as description, NOT hex code
90
+ # Rule 4: Explicit "no watermark" in both prompt and negative
91
+ # Rule 5: Clean, minimal composition
92
 
93
+ prompt = f"""Minimalist commercial poster, vertical 9:16 aspect ratio, ultra clean design.
 
 
94
 
95
+ The word "{brand_name}" in bold white sans-serif typography, centered at top, professional lettering with soft drop shadow.
96
 
97
+ Below: {poster_objects} with all screens and interfaces showing abstract colorful shapes and blurred gradients instead of text, no readable text on any UI element, purely visual design elements.
98
 
99
+ Background: {background_style}, {mood.lower()} mood, {color_description} color scheme.
100
 
101
+ Style: Apple keynote presentation quality, premium advertising, high-end product showcase, pristine studio photography, no watermarks, no signatures, no logos except the brand name."""
102
 
103
+ # Aggressive negative prompt for clean output
104
+ negative_prompt = "watermark, signature, logo, copyright, trademark, website url, username, id number, serial number, code, hex code, random letters, gibberish text, corrupted text, glitched text, small text, fine print, label, tag, badge, stamp, readable text on screens, text on monitors, text on UI, multiple texts, extra text, any text except brand name"
105
 
106
  headers = {
107
  "Authorization": f"Bearer {settings.hf_token}",
 
113
  "inputs": prompt,
114
  "parameters": {
115
  "negative_prompt": negative_prompt,
116
+ "num_inference_steps": 4,
117
+ "guidance_scale": 0.0,
118
  "width": 768,
119
  "height": 1344,
120
  }
121
  }
122
 
123
  async with httpx.AsyncClient(timeout=60.0) as client:
 
124
  response = await client.post(
125
  f"https://router.huggingface.co/hf-inference/models/{settings.flux_model}",
126
  headers=headers,