import gradio as gr import os from PIL import Image, ImageDraw, ImageFont, ImageEnhance import requests import io import json # Définition des styles ART_STYLES = { "Renaissance": { "prompt_prefix": "renaissance style masterpiece, classical composition, chiaroscuro lighting", "text_style": "elegant classical typography, golden ratio composition", "guidance": 15.0, "steps": 80, "negative_prompt": "modern, digital, low quality, blurry" }, "Impressionnisme": { "prompt_prefix": "impressionist painting style, vibrant brushstrokes, atmospheric lighting", "text_style": "artistic text integration, painterly typography", "guidance": 12.0, "steps": 65, "negative_prompt": "sharp details, digital art, photorealistic" }, "Art Moderne": { "prompt_prefix": "modern art style, geometric shapes, bold composition", "text_style": "modern typography, geometric letter design", "guidance": 11.0, "steps": 60, "negative_prompt": "traditional, realistic, detailed texture" }, "Neo Vintage": { "prompt_prefix": "vintage style poster, retro advertisement design, classic illustration", "text_style": "vintage typography, retro lettering style", "guidance": 12.5, "steps": 65, "negative_prompt": "modern, digital, contemporary" }, "Pop Art": { "prompt_prefix": "pop art style, comic book aesthetic, bold colors, halftone dots", "text_style": "bold comic book typography, retro lettering", "guidance": 11.5, "steps": 60, "negative_prompt": "subtle, realistic, painterly" } } # Effets de texte TEXT_EFFECTS = { "Standard": { "prompt_suffix": "with clear readable text", "text_params": {"weight": 1.0} }, "Néon": { "prompt_suffix": "with glowing neon text effect", "text_params": {"weight": 1.2} }, "3D": { "prompt_suffix": "with 3D text effect, depth and shadows", "text_params": {"weight": 1.3} }, "Métallique": { "prompt_suffix": "with metallic text effect, reflective surface", "text_params": {"weight": 1.1} }, "Graffiti": { "prompt_suffix": "with graffiti style text, urban art typography", "text_params": {"weight": 1.2} } } # Collections thématiques THEME_COLLECTIONS = { "Nature": { "prompts": ["natural elements", "organic composition"], "styles": ["flowing lines", "natural textures"], "negative": "artificial, synthetic" }, "Urbain": { "prompts": ["urban landscape", "city elements"], "styles": ["street art", "architectural elements"], "negative": "rural, natural" }, "Tech": { "prompts": ["technological elements", "digital aesthetic"], "styles": ["circuit patterns", "tech elements"], "negative": "organic, traditional" } } # CSS personnalisé CUSTOM_CSS = """ .container { max-width: 1200px; margin: auto; } .welcome { text-align: center; margin: 20px 0; padding: 20px; background: #1e293b; border-radius: 10px; } .quality-controls { margin: 10px 0; padding: 10px; background: #2d3748; border-radius: 5px; } .style-group { background: #2d3748; padding: 15px; border-radius: 5px; margin: 10px 0; } .text-effects { background: #374151; padding: 12px; border-radius: 5px; margin: 8px 0; } .preview-panel { position: relative; } .parameters { display: flex; gap: 10px; } """ def enhance_prompt(subject, style, text_effect, collection=None, additional_details=""): """Génération de prompt optimisée""" style_config = ART_STYLES[style] text_config = TEXT_EFFECTS[text_effect] base_prompt = f"{style_config['prompt_prefix']}, {subject}" if text_effect != "Standard": base_prompt += f", {text_config['prompt_suffix']}" if collection and collection in THEME_COLLECTIONS: collection_data = THEME_COLLECTIONS[collection] collection_elements = collection_data["prompts"] + collection_data["styles"] base_prompt += f", {', '.join(collection_elements)}" if additional_details: base_prompt += f", {additional_details}" negative_prompt = style_config['negative_prompt'] if collection: negative_prompt += f", {THEME_COLLECTIONS[collection]['negative']}" return base_prompt, negative_prompt def generate_image(format_size, orientation, subject, style, text_effect, collection, title, subtitle, quality, creativity, additional_details=""): """Fonction de génération d'image""" API_URL = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0" headers = {"Authorization": f"Bearer {os.getenv('HUGGINGFACE_TOKEN')}"} try: base_width = 1024 base_height = 1024 if orientation == "Portrait": if format_size in ["A4", "A3"]: base_width = 768 base_height = 1024 else: if format_size in ["A4", "A3"]: base_width = 1024 base_height = 768 enhanced_prompt, negative_prompt = enhance_prompt( subject, style, text_effect, collection, additional_details ) if title: enhanced_prompt += f", with text: '{title}'" if subtitle: enhanced_prompt += f", subtitle: '{subtitle}'" print(f"Prompt: {enhanced_prompt}") # Debug payload = { "inputs": enhanced_prompt, "parameters": { "negative_prompt": negative_prompt, "num_inference_steps": int(ART_STYLES[style]['steps'] * (quality/100)), "guidance_scale": ART_STYLES[style]['guidance'] * (creativity/10), "width": base_width, "height": base_height } } response = requests.post(API_URL, headers=headers, json=payload, timeout=60) if response.status_code == 200: image = Image.open(io.BytesIO(response.content)) return image, f"✨ Création {style} avec effet {text_effect} réussie!" else: print(f"Erreur API: {response.text}") return None, f"⚠️ Erreur {response.status_code}: Ajustez les paramètres" except Exception as e: print(f"Exception: {str(e)}") return None, f"⚠️ Erreur: {str(e)}" def create_interface(): with gr.Blocks(css=CUSTOM_CSS) as app: gr.HTML("""
Créez des affiches artistiques professionnelles avec notre assistant créatif augmenté.