Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import os | |
| from PIL import Image, ImageEnhance, ImageFilter | |
| import requests | |
| import io | |
| import gc | |
| import json | |
| import logging | |
| from dotenv import load_dotenv | |
| from typing import Tuple, Optional, Dict, Any, List | |
| import numpy as np | |
| from dataclasses import dataclass | |
| from reportlab.lib import colors | |
| from reportlab.lib.pagesizes import A4 | |
| from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image as RLImage, Table, TableStyle | |
| from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle | |
| from reportlab.lib.units import inch | |
| from datetime import datetime | |
| import tempfile | |
| # Configuration du logging | |
| logging.basicConfig(level=logging.DEBUG) | |
| logger = logging.getLogger("ArtistEquityPDF") | |
| class PDFGenerator: | |
| def __init__(self): | |
| self.styles = getSampleStyleSheet() | |
| self._create_custom_styles() | |
| def _create_custom_styles(self): | |
| """Création des styles personnalisés pour le PDF""" | |
| self.styles.add(ParagraphStyle( | |
| name='Title', | |
| fontSize=24, | |
| spaceAfter=30, | |
| alignment=1 | |
| )) | |
| self.styles.add(ParagraphStyle( | |
| name='Heading1', | |
| fontSize=18, | |
| spaceAfter=12, | |
| textColor=colors.HexColor('#1a365d') | |
| )) | |
| self.styles.add(ParagraphStyle( | |
| name='Heading2', | |
| fontSize=14, | |
| spaceAfter=8, | |
| textColor=colors.HexColor('#2d4a8a') | |
| )) | |
| self.styles.add(ParagraphStyle( | |
| name='Normal', | |
| fontSize=11, | |
| spaceAfter=6 | |
| )) | |
| def _format_metrics(self, metrics: Dict) -> List[List[str]]: | |
| """Formate les métriques pour le tableau PDF""" | |
| table_data = [] | |
| for category, values in metrics.items(): | |
| if isinstance(values, dict): | |
| for key, value in values.items(): | |
| if isinstance(value, float): | |
| formatted_value = f"{value:.2%}" | |
| else: | |
| formatted_value = str(value) | |
| table_data.append([category.replace('_', ' ').title(), | |
| key.replace('_', ' ').title(), | |
| formatted_value]) | |
| else: | |
| table_data.append([category.replace('_', ' ').title(), | |
| str(values), ""]) | |
| return table_data | |
| def generate_pdf(self, image: Image.Image, params: Dict[str, Any], | |
| metrics: Dict[str, Any], output_path: str) -> str: | |
| """Génère un PDF détaillé avec l'image et les métriques""" | |
| try: | |
| doc = SimpleDocTemplate( | |
| output_path, | |
| pagesize=A4, | |
| rightMargin=72, | |
| leftMargin=72, | |
| topMargin=72, | |
| bottomMargin=72 | |
| ) | |
| # Préparation des éléments du document | |
| elements = [] | |
| # En-tête | |
| elements.append(Paragraph( | |
| "Artist Equity - Rapport de Création", | |
| self.styles['Title'] | |
| )) | |
| # Date et informations de base | |
| elements.append(Paragraph( | |
| f"Généré le : {datetime.now().strftime('%d/%m/%Y %H:%M')}", | |
| self.styles['Normal'] | |
| )) | |
| elements.append(Spacer(1, 12)) | |
| # Paramètres de génération | |
| elements.append(Paragraph("Paramètres de Génération", self.styles['Heading1'])) | |
| params_table = Table([ | |
| ["Style", params['style']], | |
| ["Qualité", params['quality_preset']], | |
| ["Description", params['subject']] | |
| ]) | |
| params_table.setStyle(TableStyle([ | |
| ('BACKGROUND', (0, 0), (0, -1), colors.HexColor('#f8fafc')), | |
| ('TEXTCOLOR', (0, 0), (-1, -1), colors.HexColor('#1a365d')), | |
| ('ALIGN', (0, 0), (-1, -1), 'LEFT'), | |
| ('FONTNAME', (0, 0), (-1, -1), 'Helvetica'), | |
| ('FONTSIZE', (0, 0), (-1, -1), 10), | |
| ('BOTTOMPADDING', (0, 0), (-1, -1), 12), | |
| ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#e2e8f0')), | |
| ('GRID', (0, 0), (-1, -1), 1, colors.HexColor('#cbd5e1')) | |
| ])) | |
| elements.append(params_table) | |
| elements.append(Spacer(1, 20)) | |
| # Image générée | |
| # Sauvegarde temporaire de l'image | |
| temp_img_path = "temp_image.png" | |
| image.save(temp_img_path, "PNG") | |
| # Ajout de l'image au PDF avec dimensionnement automatique | |
| img_width = doc.width * 0.8 # 80% de la largeur de page | |
| img = RLImage(temp_img_path, width=img_width, height=img_width) | |
| elements.append(img) | |
| elements.append(Spacer(1, 20)) | |
| # Métriques de qualité | |
| elements.append(Paragraph("Métriques de Qualité", self.styles['Heading1'])) | |
| # Formatage des métriques en tableau | |
| metrics_data = self._format_metrics(metrics) | |
| metrics_table = Table( | |
| [["Catégorie", "Métrique", "Valeur"]] + metrics_data, | |
| colWidths=[doc.width/3.0]*3 | |
| ) | |
| metrics_table.setStyle(TableStyle([ | |
| ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#1a365d')), | |
| ('TEXTCOLOR', (0, 0), (-1, 0), colors.white), | |
| ('ALIGN', (0, 0), (-1, -1), 'CENTER'), | |
| ('FONTNAME', (0, 0), (-1, -1), 'Helvetica'), | |
| ('FONTSIZE', (0, 0), (-1, -1), 10), | |
| ('BOTTOMPADDING', (0, 0), (-1, -1), 12), | |
| ('GRID', (0, 0), (-1, -1), 1, colors.HexColor('#cbd5e1')), | |
| ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.HexColor('#f8fafc'), colors.white]) | |
| ])) | |
| elements.append(metrics_table) | |
| # Génération du PDF | |
| doc.build(elements) | |
| # Nettoyage | |
| os.remove(temp_img_path) | |
| return output_path | |
| except Exception as e: | |
| logger.error(f"Erreur lors de la génération du PDF: {str(e)}") | |
| raise | |
| class ArtistEquityGeneratorPDF(ArtistEquityGenerator): | |
| def __init__(self): | |
| super().__init__() | |
| self.pdf_generator = PDFGenerator() | |
| def generate_with_pdf(self, params: Dict[str, Any]) -> Tuple[Optional[Image.Image], str, str]: | |
| """Génère l'image et un PDF détaillé""" | |
| try: | |
| # Génération de l'image | |
| image, metrics = super().generate(params) | |
| if image is None: | |
| return None, None, "Erreur lors de la génération de l'image" | |
| # Création du PDF | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| pdf_filename = f"artist_equity_creation_{timestamp}.pdf" | |
| self.pdf_generator.generate_pdf( | |
| image=image, | |
| params=params, | |
| metrics=metrics, | |
| output_path=pdf_filename | |
| ) | |
| return image, pdf_filename, "✨ Création artistique et rapport PDF générés avec succès!" | |
| except Exception as e: | |
| logger.exception("Erreur lors de la génération:") | |
| return None, None, f"⚠️ Erreur: {str(e)}" | |
| def create_interface(): | |
| """Interface utilisateur avec support PDF""" | |
| generator = ArtistEquityGeneratorPDF() | |
| with gr.Blocks(theme=gr.themes.Soft(primary_hue="indigo")) as interface: | |
| gr.HTML(""" | |
| <div style="text-align: center; padding: 20px;"> | |
| <h1>🎨 Artist Equity Studio Pro</h1> | |
| <p>Création Artistique avec Documentation PDF</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| # Contrôles de génération | |
| style = gr.Dropdown( | |
| choices=list(ART_STYLES.keys()), | |
| value="Renaissance Numérique", | |
| label="Style Artistique" | |
| ) | |
| quality = gr.Radio( | |
| choices=list(QUALITY_PRESETS.keys()), | |
| value="Maître", | |
| label="Qualité" | |
| ) | |
| prompt = gr.Textbox( | |
| label="Description", | |
| placeholder="Décrivez votre vision artistique...", | |
| lines=3 | |
| ) | |
| with gr.Accordion("Paramètres Avancés", open=False): | |
| detail_level = gr.Slider( | |
| minimum=0.8, | |
| maximum=1.0, | |
| value=0.9, | |
| label="Niveau de Détail" | |
| ) | |
| color_accuracy = gr.Slider( | |
| minimum=0.8, | |
| maximum=1.0, | |
| value=0.9, | |
| label="Précision des Couleurs" | |
| ) | |
| generate_btn = gr.Button("✨ Créer", variant="primary") | |
| with gr.Column(scale=2): | |
| # Résultats | |
| image_output = gr.Image(label="Création Artistique") | |
| pdf_output = gr.File(label="Rapport PDF") | |
| status = gr.Textbox(label="Statut", interactive=False) | |
| # Logique de génération | |
| def generate_complete(*params): | |
| generation_params = { | |
| "style": params[0], | |
| "quality_preset": params[1], | |
| "subject": params[2], | |
| "detail_level": params[3], | |
| "color_accuracy": params[4] | |
| } | |
| image, pdf_path, status_msg = generator.generate_with_pdf(generation_params) | |
| return image, pdf_path, status_msg | |
| generate_btn.click( | |
| generate_complete, | |
| inputs=[style, quality, prompt, detail_level, color_accuracy], | |
| outputs=[image_output, pdf_output, status] | |
| ) | |
| return interface | |
| if __name__ == "__main__": | |
| app = create_interface() | |
| app.launch( | |
| share=False, | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| show_error=True | |
| ) |