Equityone commited on
Commit
5759851
·
verified ·
1 Parent(s): 8d16bbc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +238 -140
app.py CHANGED
@@ -5,198 +5,296 @@ import requests
5
  import io
6
  import json
7
 
8
- # Styles artistiques professionnels
9
- ART_STYLES = {
10
- "Illustration Vintage": {
11
- "prompt_prefix": "professional vintage poster illustration, high detail screen print style, limited color palette",
 
 
 
 
 
 
 
12
  "guidance": 12.5,
13
- "steps": 70
 
 
14
  },
15
- "Art Déco": {
16
- "prompt_prefix": "art deco style poster, geometric patterns, elegant composition, rich colors",
17
- "guidance": 13.0,
18
- "steps": 65
 
 
19
  },
20
- "Pop Art": {
21
- "prompt_prefix": "pop art style, bold colors, halftone dots, comic book style, Andy Warhol inspired",
22
  "guidance": 11.5,
23
- "steps": 60
24
- },
25
- "Minimaliste": {
26
- "prompt_prefix": "minimalist design, clean lines, simple shapes, bold typography",
27
- "guidance": 10.0,
28
- "steps": 55
29
- },
30
- "Street Art": {
31
- "prompt_prefix": "street art style, urban aesthetic, spray paint texture, bold contrast",
32
- "guidance": 14.0,
33
- "steps": 75
34
  }
35
  }
36
 
37
- # Collections thématiques
38
- COLLECTIONS = {
39
- "Animaux Artistiques": {
40
- "prompts": ["majestic animal portrait", "wildlife illustration"],
41
- "negative": "realistic photo, blurry, photographic"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  },
43
- "Nature Stylisée": {
44
- "prompts": ["stylized botanical art", "decorative nature elements"],
45
- "negative": "photorealistic, mundane, simple"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  },
47
- "Urbain Moderne": {
48
- "prompts": ["modern urban design", "city life illustration"],
49
- "negative": "traditional, rustic, old fashioned"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
  }
52
 
53
- def generate_pro_image(format_size, orientation, prompt, style, quality, creativity, collection=None):
54
- API_URL = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0"
55
- headers = {"Authorization": f"Bearer {os.getenv('HUGGINGFACE_TOKEN')}"}
56
-
57
- # Paramètres optimisés pour version pro
58
- dimensions = {
59
- "A4": (1024, 1448), # Augmenté pour qualité pro
60
- "A3": (1448, 2048),
61
- "A2": (2048, 2896),
62
- "A1": (2896, 4096),
63
- "A0": (4096, 5792)
64
- }
65
-
66
- try:
67
- width, height = dimensions[format_size]
68
- if orientation == "Paysage":
69
- width, height = height, width
70
-
71
- # Application du style artistique
72
- style_config = ART_STYLES[style]
73
- enhanced_prompt = f"{style_config['prompt_prefix']}, {prompt}"
74
-
75
- # Ajout des éléments de collection si spécifiés
76
- if collection and collection in COLLECTIONS:
77
- collection_prompts = COLLECTIONS[collection]["prompts"]
78
- enhanced_prompt = f"{enhanced_prompt}, {', '.join(collection_prompts)}"
79
- negative_prompt = COLLECTIONS[collection]["negative"]
80
- else:
81
- negative_prompt = "blurry, low quality, distorted, ugly, bad proportions"
82
-
83
- payload = {
84
- "inputs": enhanced_prompt,
85
- "parameters": {
86
- "negative_prompt": negative_prompt,
87
- "num_inference_steps": style_config['steps'],
88
- "guidance_scale": style_config['guidance'],
89
- "width": width,
90
- "height": height,
91
- "quality": "production", # Mode pro
92
- "seed": int(creativity * 1000), # Contrôle créatif
93
- "num_images_per_prompt": 1,
94
- "safety_checker": False, # Plus de flexibilité artistique
95
- "enhance_prompt": True,
96
- "strength": quality / 100
97
  }
98
- }
99
-
100
- response = requests.post(
101
- API_URL,
102
- headers=headers,
103
- json=payload,
104
- timeout=60 # Augmenté pour qualité pro
105
- )
106
-
107
- if response.status_code == 200:
108
- image = Image.open(io.BytesIO(response.content))
109
 
110
- # Post-traitement pro
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  enhancer = ImageEnhance.Contrast(image)
112
  image = enhancer.enhance(1.2)
113
  enhancer = ImageEnhance.Sharpness(image)
114
  image = enhancer.enhance(1.3)
115
-
116
- return image, "✨ Création artistique réussie !"
117
- return None, f"⚠️ Erreur {response.status_code}: Ajustez les paramètres"
118
-
119
- except Exception as e:
120
- print(f"Erreur détaillée: {str(e)}")
121
- return None, f"⚠️ Erreur: {str(e)}"
122
 
123
  def create_interface():
124
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="purple")) as app:
 
 
 
 
 
125
  gr.HTML("""
126
- <div style="text-align: center; padding: 20px;">
127
- <h1 style="color: #7C3AED;">🎨 Equity Artisan 3.0 Pro</h1>
128
- <p>Créez des affiches artistiques uniques avec notre IA spécialisée</p>
129
  </div>
130
  """)
131
-
132
  with gr.Row():
 
133
  with gr.Column(scale=1):
134
- format_choice = gr.Dropdown(
135
- choices=list(dimensions.keys()),
136
- value="A4",
137
- label="Format"
138
- )
139
- orientation = gr.Radio(
140
- choices=["Portrait", "Paysage"],
141
- value="Portrait",
142
- label="Orientation"
143
- )
144
-
145
- style = gr.Dropdown(
146
- choices=list(ART_STYLES.keys()),
147
- value="Illustration Vintage",
148
- label="Style Artistique"
149
- )
150
-
151
- collection = gr.Dropdown(
152
- choices=list(COLLECTIONS.keys()),
153
- label="Collection Thématique (optionnel)"
154
- )
155
-
156
  with gr.Group():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  prompt = gr.Textbox(
158
  lines=3,
159
- label="Description Artistique",
160
- placeholder="Décrivez votre vision créative..."
 
161
  )
162
-
 
 
163
  quality = gr.Slider(
164
- minimum=50,
165
  maximum=100,
166
  value=85,
167
- label="Qualité Artistique"
 
168
  )
169
-
170
  creativity = gr.Slider(
171
- minimum=1,
172
- maximum=20,
173
- value=12,
174
- label="Niveau de Créativité"
 
175
  )
176
-
177
- generate_btn = gr.Button("✨ Créer", variant="primary")
178
 
 
 
 
179
  with gr.Column(scale=2):
180
  image_output = gr.Image(
181
  label="Votre Création",
182
  type="pil"
183
  )
184
  status = gr.Textbox(
185
- label="Status",
186
  interactive=False
187
  )
188
 
189
  # Événements
190
  generate_btn.click(
191
- generate_pro_image,
192
  inputs=[
193
  format_choice,
194
  orientation,
195
- prompt,
196
  style,
 
 
197
  quality,
198
- creativity,
199
- collection
200
  ],
201
  outputs=[image_output, status]
202
  )
 
5
  import io
6
  import json
7
 
8
+ # Styles artistiques professionnels inspirés des meilleurs designers
9
+ PRO_STYLES = {
10
+ "Neo Vintage": {
11
+ "prompt_prefix": "professional high-end vintage poster, screen printing style, halftone textures, limited color palette",
12
+ "guidance": 13.5,
13
+ "steps": 75,
14
+ "negative": "photorealistic, 3d, oversaturated, amateur",
15
+ "reference": "modern vintage illustration masters"
16
+ },
17
+ "Art Contemporain": {
18
+ "prompt_prefix": "contemporary art poster, bold artistic composition, professional design, gallery quality",
19
  "guidance": 12.5,
20
+ "steps": 70,
21
+ "negative": "basic, simple, childish",
22
+ "reference": "modern art gallery style"
23
  },
24
+ "Illustration Éditoriale": {
25
+ "prompt_prefix": "professional editorial illustration, sophisticated art style, magazine quality",
26
+ "guidance": 14.0,
27
+ "steps": 80,
28
+ "negative": "basic drawing, sketchy, unrefined",
29
+ "reference": "high-end magazine art"
30
  },
31
+ "Design Minimaliste Plus": {
32
+ "prompt_prefix": "premium minimalist design, refined composition, luxury poster style",
33
  "guidance": 11.5,
34
+ "steps": 65,
35
+ "negative": "cluttered, busy, complex",
36
+ "reference": "scandinavian design principles"
 
 
 
 
 
 
 
 
37
  }
38
  }
39
 
40
+ # Collections artistiques spécialisées
41
+ ARTISTIC_COLLECTIONS = {
42
+ "Portraits Animaliers Pro": {
43
+ "base_prompts": [
44
+ "majestic animal portrait",
45
+ "artistic wildlife illustration",
46
+ "powerful animal character"
47
+ ],
48
+ "style_elements": [
49
+ "dramatic lighting",
50
+ "expressive eyes",
51
+ "detailed textures",
52
+ "strong personality"
53
+ ],
54
+ "negative": "cute, cartoon, realistic photo",
55
+ "compositions": [
56
+ "centered portrait",
57
+ "dramatic angle",
58
+ "close-up detail"
59
+ ]
60
  },
61
+ "Nature Graphique": {
62
+ "base_prompts": [
63
+ "graphic botanical art",
64
+ "stylized nature elements",
65
+ "organic patterns"
66
+ ],
67
+ "style_elements": [
68
+ "decorative details",
69
+ "flowing lines",
70
+ "dynamic composition"
71
+ ],
72
+ "negative": "photographic, plain, realistic",
73
+ "compositions": [
74
+ "geometric arrangement",
75
+ "pattern layout",
76
+ "abstract interpretation"
77
+ ]
78
  },
79
+ "Urban Art Plus": {
80
+ "base_prompts": [
81
+ "sophisticated urban art",
82
+ "street art fusion",
83
+ "modern city aesthetic"
84
+ ],
85
+ "style_elements": [
86
+ "street art textures",
87
+ "urban patterns",
88
+ "graffiti elements"
89
+ ],
90
+ "negative": "amateur graffiti, messy, unrefined",
91
+ "compositions": [
92
+ "dynamic urban composition",
93
+ "street art layout",
94
+ "modern city vibes"
95
+ ]
96
  }
97
  }
98
 
99
+ # Formats professionnels optimisés
100
+ PRO_DIMENSIONS = {
101
+ "A4+": (1152, 1634), # Optimisé pour qualité pro
102
+ "A3+": (1634, 2314),
103
+ "A2+": (2314, 3271),
104
+ "A1+": (3271, 4628),
105
+ "A0+": (4628, 6544)
106
+ }
107
+
108
+ class EquityArtisanPro:
109
+ def __init__(self):
110
+ self.model_url = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0"
111
+ self.headers = {"Authorization": f"Bearer {os.getenv('HUGGINGFACE_TOKEN')}"}
112
+
113
+ def generate_artwork(self, format_size, orientation, style, collection, prompt, quality, creativity):
114
+ try:
115
+ # Configuration des dimensions
116
+ width, height = PRO_DIMENSIONS[format_size]
117
+ if orientation == "Paysage":
118
+ width, height = height, width
119
+
120
+ # Construction du prompt artistique
121
+ style_config = PRO_STYLES[style]
122
+ collection_config = ARTISTIC_COLLECTIONS.get(collection)
123
+
124
+ # Prompt engineering avancé
125
+ enhanced_prompt = self._build_enhanced_prompt(
126
+ base_prompt=prompt,
127
+ style_config=style_config,
128
+ collection_config=collection_config
129
+ )
130
+
131
+ # Configuration avancée
132
+ payload = {
133
+ "inputs": enhanced_prompt,
134
+ "parameters": {
135
+ "negative_prompt": self._build_negative_prompt(style_config, collection_config),
136
+ "num_inference_steps": self._calculate_steps(style_config, quality),
137
+ "guidance_scale": self._calculate_guidance(style_config, creativity),
138
+ "width": width,
139
+ "height": height,
140
+ "seed": int(creativity * 1000) # Contrôle créatif
141
+ }
 
142
  }
143
+
144
+ print(f"Generating with enhanced prompt: {enhanced_prompt[:100]}...")
 
 
 
 
 
 
 
 
 
145
 
146
+ response = requests.post(
147
+ self.model_url,
148
+ headers=self.headers,
149
+ json=payload,
150
+ timeout=60
151
+ )
152
+
153
+ if response.status_code == 200:
154
+ image = Image.open(io.BytesIO(response.content))
155
+ image = self._post_process_image(image, quality)
156
+ return image, "✨ Chef d'œuvre créé avec succès!"
157
+ else:
158
+ return None, f"⚠️ Erreur {response.status_code}: {response.text}"
159
+
160
+ except Exception as e:
161
+ print(f"Error: {str(e)}")
162
+ return None, f"⚠️ Erreur: {str(e)}"
163
+
164
+ def _build_enhanced_prompt(self, base_prompt, style_config, collection_config=None):
165
+ prompt_parts = [
166
+ style_config["prompt_prefix"],
167
+ base_prompt
168
+ ]
169
+
170
+ if collection_config:
171
+ prompt_parts.extend([
172
+ f"in style of {', '.join(collection_config['style_elements'])}",
173
+ f"with {', '.join(collection_config['base_prompts'])}",
174
+ f"featuring {', '.join(collection_config['compositions'])}"
175
+ ])
176
+
177
+ return ", ".join(prompt_parts) + ", professional poster design, masterpiece quality"
178
+
179
+ def _build_negative_prompt(self, style_config, collection_config=None):
180
+ negative_parts = [
181
+ style_config["negative"],
182
+ "poor quality, amateur design, basic composition"
183
+ ]
184
+
185
+ if collection_config:
186
+ negative_parts.append(collection_config["negative"])
187
+
188
+ return ", ".join(negative_parts)
189
+
190
+ def _calculate_steps(self, style_config, quality):
191
+ base_steps = style_config["steps"]
192
+ return int(base_steps * (quality/85)) # Scaled by quality
193
+
194
+ def _calculate_guidance(self, style_config, creativity):
195
+ base_guidance = style_config["guidance"]
196
+ return base_guidance * (creativity/10) # Scaled by creativity
197
+
198
+ def _post_process_image(self, image, quality):
199
+ if quality > 85:
200
  enhancer = ImageEnhance.Contrast(image)
201
  image = enhancer.enhance(1.2)
202
  enhancer = ImageEnhance.Sharpness(image)
203
  image = enhancer.enhance(1.3)
204
+ return image
 
 
 
 
 
 
205
 
206
  def create_interface():
207
+ artisan = EquityArtisanPro()
208
+
209
+ with gr.Blocks(theme=gr.themes.Soft(
210
+ primary_hue="indigo",
211
+ secondary_hue="purple",
212
+ )) as app:
213
  gr.HTML("""
214
+ <div style="text-align: center; padding: 20px; background: linear-gradient(135deg, #4F46E5 0%, #7C3AED 100%); border-radius: 16px; margin-bottom: 24px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);">
215
+ <h1 style="color: white; font-size: 2.5em; margin-bottom: 10px;">🎨 Equity Artisan 3.0</h1>
216
+ <p style="color: #E5E7EB; font-size: 1.2em;">Créez des œuvres d'art uniques avec notre IA spécialisée</p>
217
  </div>
218
  """)
219
+
220
  with gr.Row():
221
+ # Panneau de contrôle
222
  with gr.Column(scale=1):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  with gr.Group():
224
+ gr.Markdown("### 📐 Format & Style")
225
+ format_choice = gr.Dropdown(
226
+ choices=list(PRO_DIMENSIONS.keys()),
227
+ value="A4+",
228
+ label="Format",
229
+ info="Formats optimisés pour qualité professionnelle"
230
+ )
231
+ orientation = gr.Radio(
232
+ choices=["Portrait", "Paysage"],
233
+ value="Portrait",
234
+ label="Orientation"
235
+ )
236
+ style = gr.Dropdown(
237
+ choices=list(PRO_STYLES.keys()),
238
+ value="Neo Vintage",
239
+ label="Style Artistique",
240
+ info="Styles inspirés des grands maîtres"
241
+ )
242
+
243
+ with gr.Group():
244
+ gr.Markdown("### 🎨 Vision Artistique")
245
+ collection = gr.Dropdown(
246
+ choices=list(ARTISTIC_COLLECTIONS.keys()),
247
+ label="Collection",
248
+ info="Thèmes artistiques spécialisés"
249
+ )
250
  prompt = gr.Textbox(
251
  lines=3,
252
+ label="Description",
253
+ placeholder="Décrivez votre vision artistique...",
254
+ info="Soyez précis et créatif"
255
  )
256
+
257
+ with gr.Group():
258
+ gr.Markdown("### ✨ Paramètres Créatifs")
259
  quality = gr.Slider(
260
+ minimum=70,
261
  maximum=100,
262
  value=85,
263
+ label="Qualité Artistique",
264
+ info="Influence la finesse des détails"
265
  )
 
266
  creativity = gr.Slider(
267
+ minimum=7,
268
+ maximum=15,
269
+ value=10,
270
+ label="Expression Créative",
271
+ info="Balance entre fidélité et originalité"
272
  )
 
 
273
 
274
+ generate_btn = gr.Button("✨ Créer", variant="primary", scale=1)
275
+
276
+ # Zone de prévisualisation
277
  with gr.Column(scale=2):
278
  image_output = gr.Image(
279
  label="Votre Création",
280
  type="pil"
281
  )
282
  status = gr.Textbox(
283
+ label="Statut",
284
  interactive=False
285
  )
286
 
287
  # Événements
288
  generate_btn.click(
289
+ artisan.generate_artwork,
290
  inputs=[
291
  format_choice,
292
  orientation,
 
293
  style,
294
+ collection,
295
+ prompt,
296
  quality,
297
+ creativity
 
298
  ],
299
  outputs=[image_output, status]
300
  )