|
import os |
|
from huggingface_hub import InferenceClient |
|
import gradio as gr |
|
import random |
|
import logging |
|
import sys |
|
|
|
|
|
IMAGE_MODELS = { |
|
"stabilityai/stable-diffusion-xl-base-1.0": "SDXL (Best Quality)", |
|
"runwayml/stable-diffusion-v1-5": "Stable Diffusion 1.5 (Balanced)", |
|
"stabilityai/stable-diffusion-2-1": "Stable Diffusion 2.1 (Fast)", |
|
"prompthero/openjourney": "OpenJourney (Midjourney-like)", |
|
"dreamlike-art/dreamlike-diffusion-1.0": "Dreamlike Diffusion (Artistic)" |
|
} |
|
|
|
CREATION_TYPES = { |
|
"Realistic Photo": "Create a photorealistic image with natural details and lighting", |
|
"Digital Art": "Create colorful digital artwork with clean lines and vibrant colors", |
|
"Fantasy Illustration": "Create magical and fantastical scenes with otherworldly elements", |
|
"Concept Art": "Create professional concept art for characters, environments or objects", |
|
"Anime/Manga": "Create Japanese anime or manga style illustration", |
|
"Oil Painting": "Create an image with oil painting textures and artistic brushstrokes", |
|
"Watercolor": "Create a soft watercolor illustration with subtle color blending", |
|
"Sketch": "Create a detailed sketch or drawing with line art focus", |
|
"3D Rendering": "Create an image that looks like a 3D rendered scene with realistic lighting", |
|
"Pixel Art": "Create retro-style pixel art with limited color palette" |
|
} |
|
|
|
ART_STYLES = { |
|
"Photorealistic": "detailed realistic style that resembles a photograph with accurate lighting and textures", |
|
"Impressionist": "soft brushstrokes that capture light and atmosphere over precise details, like Monet", |
|
"Surrealist": "dreamlike quality with impossible or irrational scenes, like Salvador Dali", |
|
"Pop Art": "bold colors, sharp lines and popular culture references, like Andy Warhol", |
|
"Minimalist": "simplified forms, limited color palette, and clean composition with minimal elements", |
|
"Abstract": "non-representational style using shapes, colors, and forms to express ideas", |
|
"Cubist": "geometric shapes and multiple perspectives shown simultaneously, like Picasso", |
|
"Art Nouveau": "ornate, flowing lines inspired by natural forms with decorative elegance", |
|
"Gothic": "gothic style with dark atmosphere and dramatic elements", |
|
"Cyberpunk": "futuristic dystopian style with neon colors, technology, and urban decay", |
|
"Steampunk": "steampunk style with Victorian aesthetics and brass machinery", |
|
"Retro/Vintage": "nostalgic style reminiscent of past decades with period-appropriate elements", |
|
"Art Deco": "art deco style with geometric patterns, bold colors, and luxurious materials", |
|
"Baroque": "baroque style with dramatic lighting and rich ornamentation", |
|
"Ukiyo-e": "traditional Japanese woodblock print style with flat areas of color and strong outlines", |
|
"Comic Book": "comic book style with bold outlines and vibrant colors", |
|
"Psychedelic": "psychedelic style with vibrant swirling colors and abstract patterns", |
|
"Vaporwave": "vaporwave aesthetic with glitch art and 80s/90s nostalgia", |
|
"Studio Ghibli": "Studio Ghibli anime style with whimsical detailed environments", |
|
"Hyperrealism": "hyperrealistic style with extreme detail beyond photography" |
|
} |
|
|
|
|
|
logging.basicConfig( |
|
level=logging.INFO, |
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', |
|
handlers=[logging.StreamHandler(sys.stdout)] |
|
) |
|
logger = logging.getLogger("nostalgia_nexus") |
|
|
|
|
|
def setup_client(api_key, provider=None): |
|
try: |
|
if provider: |
|
client = InferenceClient(provider=provider, api_key=api_key) |
|
logger.info(f"{provider} client initialized successfully") |
|
else: |
|
client = InferenceClient(api_key=api_key) |
|
logger.info("Hugging Face client initialized successfully") |
|
return client |
|
except Exception as e: |
|
logger.error(f"Error initializing client: {str(e)}") |
|
return None |
|
|
|
|
|
hf_api_key = os.getenv("HF_API_KEY1") or "your_hf_api_key_here" |
|
hf_client = setup_client(hf_api_key) |
|
logger.info("Hugging Face client created successfully") |
|
|
|
|
|
llama_api_key = os.getenv("HF_API_KEY2") or "your_llama_api_key_here" |
|
try: |
|
llama_client = setup_client(llama_api_key, "sambanova") |
|
use_llama = True |
|
logger.info("Llama client created successfully") |
|
except Exception as e: |
|
logger.warning(f"Llama client not available: {str(e)}. Will use fallback enhancement.") |
|
llama_client = None |
|
use_llama = False |
|
|
|
|
|
def enhance_prompt_fallback(user_input, creation_type, art_style, mood): |
|
logger.info(f"Using fallback enhancement for: {user_input[:50]}...") |
|
quality_terms = { |
|
"Realistic Photo": ["photorealistic", "high resolution", "detailed", "natural lighting", "sharp focus", "professional photography"], |
|
"Digital Art": ["vibrant colors", "clean lines", "digital illustration", "polished", "professional digital art", "detailed rendering"], |
|
"Fantasy Illustration": ["magical atmosphere", "fantasy art", "detailed illustration", "epic", "otherworldly", "imaginative scene"], |
|
"Concept Art": ["professional concept art", "detailed design", "conceptual illustration", "industry standard", "visual development", "production artwork"], |
|
"Anime/Manga": ["anime style", "manga illustration", "cel shaded", "Japanese animation", "2D character art", "anime aesthetic"], |
|
"Oil Painting": ["oil on canvas", "textured brushwork", "rich colors", "traditional painting", "artistic brushstrokes", "gallery quality"], |
|
"Watercolor": ["watercolor painting", "soft color bleeding", "delicate washes", "transparent layers", "loose brushwork", "gentle transitions"], |
|
"Sketch": ["detailed sketch", "pencil drawing", "line art", "hand-drawn", "fine details", "shading techniques"], |
|
"3D Rendering": ["3D render", "volumetric lighting", "ray tracing", "3D modeling", "realistic textures", "computer graphics"], |
|
"Pixel Art": ["pixel art", "8-bit style", "retro game aesthetic", "limited color palette", "pixelated", "nostalgic game art"] |
|
} |
|
style_modifiers = { |
|
"Photorealistic": "highly detailed photorealistic style with perfect lighting", |
|
"Impressionist": "impressionist style with visible brushstrokes capturing light and atmosphere", |
|
"Surrealist": "surrealist style with dreamlike and impossible elements", |
|
"Pop Art": "pop art style with bold colors and cultural references", |
|
"Minimalist": "minimalist style with simplified forms and limited palette", |
|
"Abstract": "abstract style using non-representational shapes and colors", |
|
"Cubist": "cubist style with geometric forms and multiple perspectives", |
|
"Art Nouveau": "art nouveau style with ornate flowing lines and natural forms", |
|
"Gothic": "gothic style with dark atmosphere and dramatic elements", |
|
"Cyberpunk": "cyberpunk style with neon colors and futuristic technology", |
|
"Steampunk": "steampunk style with Victorian aesthetics and brass machinery", |
|
"Retro/Vintage": "retro style with nostalgic elements from past decades", |
|
"Art Deco": "art deco style with geometric patterns and luxurious elements", |
|
"Baroque": "baroque style with dramatic lighting and rich ornamentation", |
|
"Ukiyo-e": "ukiyo-e style japanese woodblock print aesthetic", |
|
"Comic Book": "comic book style with bold outlines and vibrant colors", |
|
"Psychedelic": "psychedelic style with vibrant swirling colors and patterns", |
|
"Vaporwave": "vaporwave aesthetic with glitch art and 80s/90s nostalgia", |
|
"Studio Ghibli": "Studio Ghibli anime style with whimsical detailed environments", |
|
"Hyperrealism": "hyperrealistic style with extreme detail beyond photography" |
|
} |
|
mood_modifiers = { |
|
"Happy": "bright cheerful atmosphere with warm colors", |
|
"Sad": "melancholic atmosphere with muted colors", |
|
"Mysterious": "enigmatic atmosphere with shadows and hidden elements", |
|
"Peaceful": "serene calm atmosphere with gentle lighting", |
|
"Tense": "suspenseful atmosphere with dramatic lighting", |
|
"Whimsical": "playful whimsical atmosphere with imaginative elements", |
|
"Dark": "dark gloomy atmosphere with deep shadows", |
|
"Energetic": "dynamic vibrant atmosphere with strong colors", |
|
"Romantic": "soft romantic atmosphere with dreamy lighting", |
|
"Epic": "grand epic atmosphere with dramatic scale" |
|
} |
|
type_terms = quality_terms.get(creation_type, ["high quality", "detailed", "professional", "masterful"]) |
|
common_terms = ["8K resolution", "highly detailed", "professional", "trending on artstation", "masterpiece"] |
|
style_modifier = style_modifiers.get(art_style, "detailed style") |
|
mood_modifier = mood_modifiers.get(mood, "atmospheric") |
|
prompt_parts = [user_input, style_modifier, mood_modifier] |
|
selected_type_terms = random.sample(type_terms, min(3, len(type_terms))) |
|
selected_common_terms = random.sample(common_terms, min(2, len(common_terms))) |
|
quality_description = ", ".join(selected_type_terms + selected_common_terms) |
|
enhanced_prompt = f"{', '.join(prompt_parts)}, {quality_description}" |
|
logger.info(f"Fallback enhanced prompt: {enhanced_prompt[:100]}...") |
|
return enhanced_prompt |
|
|
|
|
|
def enhance_prompt_with_llama(user_input, creation_type, art_style, mood): |
|
try: |
|
if not use_llama or llama_client is None: |
|
logger.warning("Llama enhancement not available, using fallback") |
|
return enhance_prompt_fallback(user_input, creation_type, art_style, mood) |
|
logger.info(f"Enhancing prompt with Llama 4 for creation type: {creation_type}, art style: {art_style}") |
|
system_prompt = """You are a world-class prompt engineer who specializes in creating detailed, effective prompts for text-to-image AI models. |
|
|
|
Your task is to transform a user's simple description into a comprehensive, detailed image generation prompt that will create stunning visuals. Consider all the provided elements (description, creation type, art style, mood) and combine them into a cohesive, detailed prompt. |
|
|
|
MOST IMPORTANTLY - ADD LOGICAL DETAILS: |
|
- Analyze what the user wants and add logical details that would make the scene realistic or coherent |
|
- If describing something fantastical (e.g., "flying cat"), add logical details about how this could work (e.g., "a cat with majestic feathered wings spread wide") |
|
- Think about environment, lighting, perspective, time of day, weather, and other contextual elements |
|
- Create a vivid, imaginable scene with spatial relationships clearly defined |
|
|
|
PROMPT STRUCTURE GUIDELINES: |
|
1. Start with the core subject and its primary characteristics |
|
2. Add environment and setting details |
|
3. Describe lighting, atmosphere, and mood |
|
4. Include specific visual style and artistic technique references |
|
5. Add technical quality terms (8K, detailed, masterful, etc.) |
|
|
|
FORMAT YOUR RESPONSE AS A SINGLE PARAGRAPH with no additional comments, explanations, or bullet points. Use natural language without awkward comma separations. Aim for 75-150 words. |
|
|
|
AVOID: |
|
- Do not include quotation marks in your response |
|
- Do not preface with "here's a prompt" or similar text |
|
- Do not use placeholders |
|
- Do not add negative prompts |
|
- Do not write in list format or use bullet points |
|
|
|
Respond only with the enhanced prompt and nothing else.""" |
|
creation_description = CREATION_TYPES.get(creation_type, "Create a detailed image") |
|
style_description = ART_STYLES.get(art_style, "with detailed and professional quality") |
|
user_prompt = f"Description: {user_input}\nCreation Type: {creation_type} - {creation_description}\nArt Style: {art_style} - {style_description}\nMood: {mood}\n\nPlease create a comprehensive, detailed image generation prompt that combines all these elements." |
|
completion = llama_client.chat.completions.create( |
|
model="meta-llama/Llama-4-Scout-17B-16E-Instruct", |
|
messages=[ |
|
{"role": "system", "content": system_prompt}, |
|
{"role": "user", "content": user_prompt} |
|
], |
|
max_tokens=500, |
|
) |
|
enhanced = completion.choices[0].message.content |
|
logger.info(f"Llama 4 enhanced prompt: {enhanced[:100]}...") |
|
return enhanced if enhanced else user_input |
|
except Exception as e: |
|
logger.error(f"Error during Llama enhancement: {str(e)}") |
|
return enhance_prompt_fallback(user_input, creation_type, art_style, mood) |
|
|
|
|
|
def generate_image(description, creation_type, art_style, mood, model_name): |
|
try: |
|
logger.info(f"Generating image with model: {model_name}") |
|
enhanced_prompt = enhance_prompt_with_llama(description, creation_type, art_style, mood) |
|
if hf_client is None: |
|
logger.error("Hugging Face client not available") |
|
return None, "Error: Hugging Face client not available", enhanced_prompt |
|
logger.info(f"Sending request to model {model_name} with prompt: {enhanced_prompt[:100]}...") |
|
image = hf_client.text_to_image( |
|
prompt=enhanced_prompt, |
|
model=model_name, |
|
negative_prompt="low quality, blurry, distorted, deformed, disfigured, bad anatomy, watermark, signature, text" |
|
) |
|
logger.info("Image generated successfully") |
|
analysis = f"Image generated using model: <b style='color:#FF6F61;'>{IMAGE_MODELS.get(model_name, model_name)}</b>\n" |
|
if use_llama: |
|
analysis += "Prompt enhanced with <b style='color:#FF6F61;'>Llama 4</b>" |
|
else: |
|
analysis += "Prompt enhanced with fallback method" |
|
return image, analysis, enhanced_prompt |
|
except Exception as e: |
|
logger.error(f"Error generating image: {str(e)}") |
|
return None, f"Error generating image: {str(e)}", enhanced_prompt |
|
|
|
|
|
with gr.Blocks(title="Nostalgia Nexus") as interface: |
|
|
|
gr.HTML( |
|
""" |
|
<style> |
|
body { background-color: #fdfdfd; } |
|
.gradio-container { font-family: 'Arial', sans-serif; } |
|
.header-title { text-align: center; color: #FF6F61; font-size: 2.5em; font-weight: bold; } |
|
.header-subtitle { text-align: center; color: #6B5B95; font-size: 1.5em; margin-bottom: 20px; } |
|
</style> |
|
""" |
|
) |
|
|
|
|
|
gr.Markdown( |
|
""" |
|
<h1 class="header-title">🎨 Nostalgia Nexus</h1> |
|
<h3 class="header-subtitle">Transform your childhood memories into stunning images with AI</h3> |
|
""" |
|
) |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
|
|
description_input = gr.Textbox( |
|
label="Describe what you want to see", |
|
placeholder="Be detailed and specific about what you want in the image...", |
|
lines=4 |
|
) |
|
with gr.Row(): |
|
creation_type = gr.Dropdown( |
|
choices=list(CREATION_TYPES.keys()), |
|
value="Digital Art", |
|
label="Creation Type" |
|
) |
|
model_selector = gr.Dropdown( |
|
choices=list(IMAGE_MODELS.keys()), |
|
value="stabilityai/stable-diffusion-xl-base-1.0", |
|
label="Image Model" |
|
) |
|
with gr.Row(): |
|
art_style = gr.Dropdown( |
|
choices=list(ART_STYLES.keys()), |
|
value="Photorealistic", |
|
label="Art Style" |
|
) |
|
mood_dropdown = gr.Dropdown( |
|
choices=["Happy", "Sad", "Mysterious", "Peaceful", "Tense", |
|
"Whimsical", "Dark", "Energetic", "Romantic", "Epic"], |
|
value="Peaceful", |
|
label="Mood" |
|
) |
|
generate_button = gr.Button("✨ Generate Image", variant="primary", size="lg") |
|
|
|
def format_model_name(model_key): |
|
return IMAGE_MODELS.get(model_key, model_key) |
|
model_label = gr.HTML(value="") |
|
model_selector.change( |
|
fn=lambda x: f"<p style='color: #FF6F61; font-weight: bold;'>Selected model: {format_model_name(x)}</p>", |
|
inputs=model_selector, |
|
outputs=model_label |
|
) |
|
with gr.Column(): |
|
|
|
image_output = gr.Image(label="Generated Image") |
|
with gr.Accordion("Enhanced Prompt", open=False): |
|
prompt_output = gr.Textbox(label="AI-Enhanced Prompt Used", lines=6) |
|
|
|
generate_button.click( |
|
fn=generate_image, |
|
inputs=[description_input, creation_type, art_style, mood_dropdown, model_selector], |
|
outputs=[image_output, model_label, prompt_output] |
|
) |
|
|
|
|
|
with gr.Accordion("Tips for better results", open=True): |
|
gr.Markdown( |
|
""" |
|
<div style="background-color: #FFF3E0; padding: 10px; border-radius: 5px;"> |
|
<h4 style="color: #FF6F61;">💡 Tips for better results:</h4> |
|
<ul> |
|
<li><b>Be specific</b>: include details about subjects, actions, and settings.</li> |
|
<li><b>Mention colors, textures, and lighting</b> to enhance your vision.</li> |
|
<li><b>Try different art styles</b> to change the overall mood.</li> |
|
<li><b>Select the mood</b> to influence the final atmosphere.</li> |
|
<li><b>SDXL model</b> generally yields the highest quality images, albeit slower.</li> |
|
</ul> |
|
<p><i>Examples:</i></p> |
|
<ul> |
|
<li>"A serene lake at sunset with mountains in the background and a small wooden boat floating nearby"</li> |
|
<li>"A futuristic cityscape with flying cars, neon lights, and skyscrapers under a dual-moon night sky"</li> |
|
<li>"An elderly craftsman with weathered hands meticulously carving a detailed wooden sculpture"</li> |
|
</ul> |
|
</div> |
|
""" |
|
) |
|
|
|
with gr.Accordion("Troubleshooting", open=False): |
|
gr.Markdown( |
|
""" |
|
<div style="background-color: #F8D7DA; padding: 10px; border-radius: 5px;"> |
|
<h4 style="color: #C82333;">Troubleshooting Tips</h4> |
|
<ol> |
|
<li>Check the console/terminal for detailed logs.</li> |
|
<li>Verify your Hugging Face API key and its permissions.</li> |
|
<li>Try a different model if access errors occur.</li> |
|
<li>Simplify your prompt if it is overly long or complex.</li> |
|
<li>Restart the app if it has been running for a long time.</li> |
|
</ol> |
|
<p>Common errors include 401/403 (authentication/model access issues), 429 (rate limiting), and 503 (service unavailability).</p> |
|
</div> |
|
""" |
|
) |
|
|
|
|
|
interface.launch() |
|
|