Equityone commited on
Commit
9ad2ed4
·
verified ·
1 Parent(s): a3e339a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +259 -126
app.py CHANGED
@@ -1,151 +1,284 @@
1
  import gradio as gr
2
- import torch
3
- import gc
4
- from diffusers import StableDiffusionPipeline
5
- from transformers import logging
6
  import os
7
- from dataclasses import dataclass
8
- from typing import Optional, Dict, Any
 
 
 
 
 
 
9
  import numpy as np
 
 
 
 
 
 
 
 
10
 
11
- # Configuration système optimisée
12
- @dataclass
13
- class SystemConfig:
14
- """Configuration système optimisée"""
15
- model_id: str = "CompVis/stable-diffusion-v1-4" # Modèle plus léger que SDXL
16
- torch_dtype: torch.dtype = torch.float32 # Plus stable sur CPU
17
- image_size: int = 512
18
- optimization_level: str = "balanced"
19
- max_batch_size: int = 1
20
-
21
- steps_config = {
22
- "fast": 15,
23
- "balanced": 25,
24
- "quality": 35
25
- }
26
-
27
- class ImageGenerator:
28
- def __init__(self, config: SystemConfig):
29
- self.config = config
30
- self.model = None
31
- self.styles = {
32
- "Réaliste": {
33
- "prompt": "professional photograph, highly detailed, sharp focus {}",
34
- "negative": "cartoon, painting, artwork, drawing, anime"
35
- },
36
- "Artistique": {
37
- "prompt": "artistic masterpiece, creative interpretation {}",
38
- "negative": "photo, photorealistic, mundane"
39
- },
40
- "Moderne": {
41
- "prompt": "modern digital art, trending on artstation {}",
42
- "negative": "outdated, classic, traditional"
43
- }
44
- }
45
-
46
- def initialize_model(self):
47
- """Initialisation optimisée du modèle"""
48
- if self.model is None:
49
- gc.collect()
50
- self.model = StableDiffusionPipeline.from_pretrained(
51
- self.config.model_id,
52
- torch_dtype=self.config.torch_dtype,
53
- safety_checker=None,
54
- requires_safety_checker=False
55
- ).to("cpu")
56
- self.model.enable_attention_slicing()
57
- self.model.enable_vae_slicing()
58
- return self.model
59
-
60
- def generate_image(
61
- self,
62
- prompt: str,
63
- style: str = "Réaliste",
64
- seed: int = -1,
65
- optimization_level: str = "balanced"
66
- ) -> np.ndarray:
67
- """Génération d'image avec gestion optimisée des ressources"""
 
 
68
  try:
69
- model = self.initialize_model()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
- # Préparation du prompt
72
- base_style = self.styles[style]
73
- full_prompt = base_style["prompt"].format(prompt)
74
- negative_prompt = base_style["negative"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
- # Configuration des étapes selon l'optimisation
77
- num_steps = self.config.steps_config[optimization_level]
 
 
 
 
 
 
78
 
79
- # Gestion de la seed
80
- if seed != -1:
81
- torch.manual_seed(seed)
82
-
83
- # Génération
84
- with torch.no_grad():
85
- image = model(
86
- prompt=full_prompt,
87
- negative_prompt=negative_prompt,
88
- num_inference_steps=num_steps,
89
- height=self.config.image_size,
90
- width=self.config.image_size,
91
- ).images[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
- return image
 
 
 
 
 
94
 
 
 
 
 
 
 
 
 
 
95
  except Exception as e:
96
- print(f"Erreur lors de la génération: {str(e)}")
97
- raise e
98
- finally:
99
- gc.collect()
100
 
101
- # Interface Gradio
102
  def create_interface():
103
- # Initialisation
104
- config = SystemConfig()
105
- generator = ImageGenerator(config)
106
 
107
- # Définition de l'interface
108
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
109
- gr.Markdown("# Générateur d'Images Professionnel")
110
-
 
 
 
 
111
  with gr.Row():
112
- with gr.Column(scale=2):
113
- prompt = gr.Textbox(
114
- label="Description de l'image souhaitée",
115
- placeholder="Décrivez l'image que vous souhaitez générer..."
116
- )
117
  style = gr.Dropdown(
118
- choices=list(generator.styles.keys()),
119
- value="Réaliste",
120
- label="Style"
 
 
 
 
 
 
 
 
 
 
 
 
121
  )
122
- with gr.Row():
123
- seed = gr.Number(
124
- value=-1,
125
- label="Seed (-1 pour aléatoire)",
126
- precision=0
 
 
127
  )
128
- optimization = gr.Dropdown(
129
- choices=list(config.steps_config.keys()),
130
- value="balanced",
131
- label="Niveau d'optimisation"
 
132
  )
133
-
134
- generate_btn = gr.Button("Générer", variant="primary")
135
-
136
  with gr.Column(scale=2):
137
- output = gr.Image(label="Image générée")
138
-
 
 
 
139
  # Logique de génération
 
 
 
 
 
 
 
 
 
 
 
 
140
  generate_btn.click(
141
- fn=generator.generate_image,
142
- inputs=[prompt, style, seed, optimization],
143
- outputs=output
144
  )
145
-
146
- return demo
147
 
148
- # Lancement de l'interface
 
149
  if __name__ == "__main__":
150
- demo = create_interface()
151
- demo.launch()
 
 
 
 
 
 
1
  import gradio as gr
 
 
 
 
2
  import os
3
+ from PIL import Image, ImageEnhance, ImageFilter
4
+ import requests
5
+ import io
6
+ import gc
7
+ import json
8
+ import logging
9
+ from dotenv import load_dotenv
10
+ from typing import Tuple, Optional, Dict, Any, List
11
  import numpy as np
12
+ from dataclasses import dataclass
13
+ from reportlab.lib import colors
14
+ from reportlab.lib.pagesizes import A4
15
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image as RLImage, Table, TableStyle
16
+ from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
17
+ from reportlab.lib.units import inch
18
+ from datetime import datetime
19
+ import tempfile
20
 
21
+ # Configuration du logging
22
+ logging.basicConfig(level=logging.DEBUG)
23
+ logger = logging.getLogger("ArtistEquityPDF")
24
+
25
+ class PDFGenerator:
26
+ def __init__(self):
27
+ self.styles = getSampleStyleSheet()
28
+ self._create_custom_styles()
29
+
30
+ def _create_custom_styles(self):
31
+ """Création des styles personnalisés pour le PDF"""
32
+ self.styles.add(ParagraphStyle(
33
+ name='Title',
34
+ fontSize=24,
35
+ spaceAfter=30,
36
+ alignment=1
37
+ ))
38
+
39
+ self.styles.add(ParagraphStyle(
40
+ name='Heading1',
41
+ fontSize=18,
42
+ spaceAfter=12,
43
+ textColor=colors.HexColor('#1a365d')
44
+ ))
45
+
46
+ self.styles.add(ParagraphStyle(
47
+ name='Heading2',
48
+ fontSize=14,
49
+ spaceAfter=8,
50
+ textColor=colors.HexColor('#2d4a8a')
51
+ ))
52
+
53
+ self.styles.add(ParagraphStyle(
54
+ name='Normal',
55
+ fontSize=11,
56
+ spaceAfter=6
57
+ ))
58
+
59
+ def _format_metrics(self, metrics: Dict) -> List[List[str]]:
60
+ """Formate les métriques pour le tableau PDF"""
61
+ table_data = []
62
+ for category, values in metrics.items():
63
+ if isinstance(values, dict):
64
+ for key, value in values.items():
65
+ if isinstance(value, float):
66
+ formatted_value = f"{value:.2%}"
67
+ else:
68
+ formatted_value = str(value)
69
+ table_data.append([category.replace('_', ' ').title(),
70
+ key.replace('_', ' ').title(),
71
+ formatted_value])
72
+ else:
73
+ table_data.append([category.replace('_', ' ').title(),
74
+ str(values), ""])
75
+ return table_data
76
+
77
+ def generate_pdf(self, image: Image.Image, params: Dict[str, Any],
78
+ metrics: Dict[str, Any], output_path: str) -> str:
79
+ """Génère un PDF détaillé avec l'image et les métriques"""
80
  try:
81
+ doc = SimpleDocTemplate(
82
+ output_path,
83
+ pagesize=A4,
84
+ rightMargin=72,
85
+ leftMargin=72,
86
+ topMargin=72,
87
+ bottomMargin=72
88
+ )
89
+
90
+ # Préparation des éléments du document
91
+ elements = []
92
+
93
+ # En-tête
94
+ elements.append(Paragraph(
95
+ "Artist Equity - Rapport de Création",
96
+ self.styles['Title']
97
+ ))
98
 
99
+ # Date et informations de base
100
+ elements.append(Paragraph(
101
+ f"Généré le : {datetime.now().strftime('%d/%m/%Y %H:%M')}",
102
+ self.styles['Normal']
103
+ ))
104
+ elements.append(Spacer(1, 12))
105
+
106
+ # Paramètres de génération
107
+ elements.append(Paragraph("Paramètres de Génération", self.styles['Heading1']))
108
+ params_table = Table([
109
+ ["Style", params['style']],
110
+ ["Qualité", params['quality_preset']],
111
+ ["Description", params['subject']]
112
+ ])
113
+ params_table.setStyle(TableStyle([
114
+ ('BACKGROUND', (0, 0), (0, -1), colors.HexColor('#f8fafc')),
115
+ ('TEXTCOLOR', (0, 0), (-1, -1), colors.HexColor('#1a365d')),
116
+ ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
117
+ ('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
118
+ ('FONTSIZE', (0, 0), (-1, -1), 10),
119
+ ('BOTTOMPADDING', (0, 0), (-1, -1), 12),
120
+ ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#e2e8f0')),
121
+ ('GRID', (0, 0), (-1, -1), 1, colors.HexColor('#cbd5e1'))
122
+ ]))
123
+ elements.append(params_table)
124
+ elements.append(Spacer(1, 20))
125
+
126
+ # Image générée
127
+ # Sauvegarde temporaire de l'image
128
+ temp_img_path = "temp_image.png"
129
+ image.save(temp_img_path, "PNG")
130
 
131
+ # Ajout de l'image au PDF avec dimensionnement automatique
132
+ img_width = doc.width * 0.8 # 80% de la largeur de page
133
+ img = RLImage(temp_img_path, width=img_width, height=img_width)
134
+ elements.append(img)
135
+ elements.append(Spacer(1, 20))
136
+
137
+ # Métriques de qualité
138
+ elements.append(Paragraph("Métriques de Qualité", self.styles['Heading1']))
139
 
140
+ # Formatage des métriques en tableau
141
+ metrics_data = self._format_metrics(metrics)
142
+ metrics_table = Table(
143
+ [["Catégorie", "Métrique", "Valeur"]] + metrics_data,
144
+ colWidths=[doc.width/3.0]*3
145
+ )
146
+ metrics_table.setStyle(TableStyle([
147
+ ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#1a365d')),
148
+ ('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
149
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
150
+ ('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
151
+ ('FONTSIZE', (0, 0), (-1, -1), 10),
152
+ ('BOTTOMPADDING', (0, 0), (-1, -1), 12),
153
+ ('GRID', (0, 0), (-1, -1), 1, colors.HexColor('#cbd5e1')),
154
+ ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.HexColor('#f8fafc'), colors.white])
155
+ ]))
156
+ elements.append(metrics_table)
157
+
158
+ # Génération du PDF
159
+ doc.build(elements)
160
+
161
+ # Nettoyage
162
+ os.remove(temp_img_path)
163
+
164
+ return output_path
165
+
166
+ except Exception as e:
167
+ logger.error(f"Erreur lors de la génération du PDF: {str(e)}")
168
+ raise
169
+
170
+ class ArtistEquityGeneratorPDF(ArtistEquityGenerator):
171
+ def __init__(self):
172
+ super().__init__()
173
+ self.pdf_generator = PDFGenerator()
174
+
175
+ def generate_with_pdf(self, params: Dict[str, Any]) -> Tuple[Optional[Image.Image], str, str]:
176
+ """Génère l'image et un PDF détaillé"""
177
+ try:
178
+ # Génération de l'image
179
+ image, metrics = super().generate(params)
180
 
181
+ if image is None:
182
+ return None, None, "Erreur lors de la génération de l'image"
183
+
184
+ # Création du PDF
185
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
186
+ pdf_filename = f"artist_equity_creation_{timestamp}.pdf"
187
 
188
+ self.pdf_generator.generate_pdf(
189
+ image=image,
190
+ params=params,
191
+ metrics=metrics,
192
+ output_path=pdf_filename
193
+ )
194
+
195
+ return image, pdf_filename, "✨ Création artistique et rapport PDF générés avec succès!"
196
+
197
  except Exception as e:
198
+ logger.exception("Erreur lors de la génération:")
199
+ return None, None, f"⚠️ Erreur: {str(e)}"
 
 
200
 
 
201
  def create_interface():
202
+ """Interface utilisateur avec support PDF"""
203
+ generator = ArtistEquityGeneratorPDF()
 
204
 
205
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="indigo")) as interface:
206
+ gr.HTML("""
207
+ <div style="text-align: center; padding: 20px;">
208
+ <h1>🎨 Artist Equity Studio Pro</h1>
209
+ <p>Création Artistique avec Documentation PDF</p>
210
+ </div>
211
+ """)
212
+
213
  with gr.Row():
214
+ with gr.Column(scale=1):
215
+ # Contrôles de génération
 
 
 
216
  style = gr.Dropdown(
217
+ choices=list(ART_STYLES.keys()),
218
+ value="Renaissance Numérique",
219
+ label="Style Artistique"
220
+ )
221
+
222
+ quality = gr.Radio(
223
+ choices=list(QUALITY_PRESETS.keys()),
224
+ value="Maître",
225
+ label="Qualité"
226
+ )
227
+
228
+ prompt = gr.Textbox(
229
+ label="Description",
230
+ placeholder="Décrivez votre vision artistique...",
231
+ lines=3
232
  )
233
+
234
+ with gr.Accordion("Paramètres Avancés", open=False):
235
+ detail_level = gr.Slider(
236
+ minimum=0.8,
237
+ maximum=1.0,
238
+ value=0.9,
239
+ label="Niveau de Détail"
240
  )
241
+ color_accuracy = gr.Slider(
242
+ minimum=0.8,
243
+ maximum=1.0,
244
+ value=0.9,
245
+ label="Précision des Couleurs"
246
  )
247
+
248
+ generate_btn = gr.Button("✨ Créer", variant="primary")
249
+
250
  with gr.Column(scale=2):
251
+ # Résultats
252
+ image_output = gr.Image(label="Création Artistique")
253
+ pdf_output = gr.File(label="Rapport PDF")
254
+ status = gr.Textbox(label="Statut", interactive=False)
255
+
256
  # Logique de génération
257
+ def generate_complete(*params):
258
+ generation_params = {
259
+ "style": params[0],
260
+ "quality_preset": params[1],
261
+ "subject": params[2],
262
+ "detail_level": params[3],
263
+ "color_accuracy": params[4]
264
+ }
265
+
266
+ image, pdf_path, status_msg = generator.generate_with_pdf(generation_params)
267
+ return image, pdf_path, status_msg
268
+
269
  generate_btn.click(
270
+ generate_complete,
271
+ inputs=[style, quality, prompt, detail_level, color_accuracy],
272
+ outputs=[image_output, pdf_output, status]
273
  )
 
 
274
 
275
+ return interface
276
+
277
  if __name__ == "__main__":
278
+ app = create_interface()
279
+ app.launch(
280
+ share=False,
281
+ server_name="0.0.0.0",
282
+ server_port=7860,
283
+ show_error=True
284
+ )