generart / app.py
Equityone's picture
Update app.py
5759851 verified
raw
history blame
11 kB
import gradio as gr
import os
from PIL import Image, ImageDraw, ImageFont, ImageEnhance
import requests
import io
import json
# Styles artistiques professionnels inspirés des meilleurs designers
PRO_STYLES = {
"Neo Vintage": {
"prompt_prefix": "professional high-end vintage poster, screen printing style, halftone textures, limited color palette",
"guidance": 13.5,
"steps": 75,
"negative": "photorealistic, 3d, oversaturated, amateur",
"reference": "modern vintage illustration masters"
},
"Art Contemporain": {
"prompt_prefix": "contemporary art poster, bold artistic composition, professional design, gallery quality",
"guidance": 12.5,
"steps": 70,
"negative": "basic, simple, childish",
"reference": "modern art gallery style"
},
"Illustration Éditoriale": {
"prompt_prefix": "professional editorial illustration, sophisticated art style, magazine quality",
"guidance": 14.0,
"steps": 80,
"negative": "basic drawing, sketchy, unrefined",
"reference": "high-end magazine art"
},
"Design Minimaliste Plus": {
"prompt_prefix": "premium minimalist design, refined composition, luxury poster style",
"guidance": 11.5,
"steps": 65,
"negative": "cluttered, busy, complex",
"reference": "scandinavian design principles"
}
}
# Collections artistiques spécialisées
ARTISTIC_COLLECTIONS = {
"Portraits Animaliers Pro": {
"base_prompts": [
"majestic animal portrait",
"artistic wildlife illustration",
"powerful animal character"
],
"style_elements": [
"dramatic lighting",
"expressive eyes",
"detailed textures",
"strong personality"
],
"negative": "cute, cartoon, realistic photo",
"compositions": [
"centered portrait",
"dramatic angle",
"close-up detail"
]
},
"Nature Graphique": {
"base_prompts": [
"graphic botanical art",
"stylized nature elements",
"organic patterns"
],
"style_elements": [
"decorative details",
"flowing lines",
"dynamic composition"
],
"negative": "photographic, plain, realistic",
"compositions": [
"geometric arrangement",
"pattern layout",
"abstract interpretation"
]
},
"Urban Art Plus": {
"base_prompts": [
"sophisticated urban art",
"street art fusion",
"modern city aesthetic"
],
"style_elements": [
"street art textures",
"urban patterns",
"graffiti elements"
],
"negative": "amateur graffiti, messy, unrefined",
"compositions": [
"dynamic urban composition",
"street art layout",
"modern city vibes"
]
}
}
# Formats professionnels optimisés
PRO_DIMENSIONS = {
"A4+": (1152, 1634), # Optimisé pour qualité pro
"A3+": (1634, 2314),
"A2+": (2314, 3271),
"A1+": (3271, 4628),
"A0+": (4628, 6544)
}
class EquityArtisanPro:
def __init__(self):
self.model_url = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0"
self.headers = {"Authorization": f"Bearer {os.getenv('HUGGINGFACE_TOKEN')}"}
def generate_artwork(self, format_size, orientation, style, collection, prompt, quality, creativity):
try:
# Configuration des dimensions
width, height = PRO_DIMENSIONS[format_size]
if orientation == "Paysage":
width, height = height, width
# Construction du prompt artistique
style_config = PRO_STYLES[style]
collection_config = ARTISTIC_COLLECTIONS.get(collection)
# Prompt engineering avancé
enhanced_prompt = self._build_enhanced_prompt(
base_prompt=prompt,
style_config=style_config,
collection_config=collection_config
)
# Configuration avancée
payload = {
"inputs": enhanced_prompt,
"parameters": {
"negative_prompt": self._build_negative_prompt(style_config, collection_config),
"num_inference_steps": self._calculate_steps(style_config, quality),
"guidance_scale": self._calculate_guidance(style_config, creativity),
"width": width,
"height": height,
"seed": int(creativity * 1000) # Contrôle créatif
}
}
print(f"Generating with enhanced prompt: {enhanced_prompt[:100]}...")
response = requests.post(
self.model_url,
headers=self.headers,
json=payload,
timeout=60
)
if response.status_code == 200:
image = Image.open(io.BytesIO(response.content))
image = self._post_process_image(image, quality)
return image, "✨ Chef d'œuvre créé avec succès!"
else:
return None, f"⚠️ Erreur {response.status_code}: {response.text}"
except Exception as e:
print(f"Error: {str(e)}")
return None, f"⚠️ Erreur: {str(e)}"
def _build_enhanced_prompt(self, base_prompt, style_config, collection_config=None):
prompt_parts = [
style_config["prompt_prefix"],
base_prompt
]
if collection_config:
prompt_parts.extend([
f"in style of {', '.join(collection_config['style_elements'])}",
f"with {', '.join(collection_config['base_prompts'])}",
f"featuring {', '.join(collection_config['compositions'])}"
])
return ", ".join(prompt_parts) + ", professional poster design, masterpiece quality"
def _build_negative_prompt(self, style_config, collection_config=None):
negative_parts = [
style_config["negative"],
"poor quality, amateur design, basic composition"
]
if collection_config:
negative_parts.append(collection_config["negative"])
return ", ".join(negative_parts)
def _calculate_steps(self, style_config, quality):
base_steps = style_config["steps"]
return int(base_steps * (quality/85)) # Scaled by quality
def _calculate_guidance(self, style_config, creativity):
base_guidance = style_config["guidance"]
return base_guidance * (creativity/10) # Scaled by creativity
def _post_process_image(self, image, quality):
if quality > 85:
enhancer = ImageEnhance.Contrast(image)
image = enhancer.enhance(1.2)
enhancer = ImageEnhance.Sharpness(image)
image = enhancer.enhance(1.3)
return image
def create_interface():
artisan = EquityArtisanPro()
with gr.Blocks(theme=gr.themes.Soft(
primary_hue="indigo",
secondary_hue="purple",
)) as app:
gr.HTML("""
<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);">
<h1 style="color: white; font-size: 2.5em; margin-bottom: 10px;">🎨 Equity Artisan 3.0</h1>
<p style="color: #E5E7EB; font-size: 1.2em;">Créez des œuvres d'art uniques avec notre IA spécialisée</p>
</div>
""")
with gr.Row():
# Panneau de contrôle
with gr.Column(scale=1):
with gr.Group():
gr.Markdown("### 📐 Format & Style")
format_choice = gr.Dropdown(
choices=list(PRO_DIMENSIONS.keys()),
value="A4+",
label="Format",
info="Formats optimisés pour qualité professionnelle"
)
orientation = gr.Radio(
choices=["Portrait", "Paysage"],
value="Portrait",
label="Orientation"
)
style = gr.Dropdown(
choices=list(PRO_STYLES.keys()),
value="Neo Vintage",
label="Style Artistique",
info="Styles inspirés des grands maîtres"
)
with gr.Group():
gr.Markdown("### 🎨 Vision Artistique")
collection = gr.Dropdown(
choices=list(ARTISTIC_COLLECTIONS.keys()),
label="Collection",
info="Thèmes artistiques spécialisés"
)
prompt = gr.Textbox(
lines=3,
label="Description",
placeholder="Décrivez votre vision artistique...",
info="Soyez précis et créatif"
)
with gr.Group():
gr.Markdown("### ✨ Paramètres Créatifs")
quality = gr.Slider(
minimum=70,
maximum=100,
value=85,
label="Qualité Artistique",
info="Influence la finesse des détails"
)
creativity = gr.Slider(
minimum=7,
maximum=15,
value=10,
label="Expression Créative",
info="Balance entre fidélité et originalité"
)
generate_btn = gr.Button("✨ Créer", variant="primary", scale=1)
# Zone de prévisualisation
with gr.Column(scale=2):
image_output = gr.Image(
label="Votre Création",
type="pil"
)
status = gr.Textbox(
label="Statut",
interactive=False
)
# Événements
generate_btn.click(
artisan.generate_artwork,
inputs=[
format_choice,
orientation,
style,
collection,
prompt,
quality,
creativity
],
outputs=[image_output, status]
)
return app
if __name__ == "__main__":
app = create_interface()
app.launch()