import gradio as gr from PIL import Image, ImageDraw, ImageFont import random import colorsys import io def generate_gradient(width, height, color_hue, intensity): """Generates a vertical gradient image based on hue and intensity.""" img = Image.new("RGB", (width, height)) draw = ImageDraw.Draw(img) # Convert HSV to RGB r1, g1, b1 = colorsys.hsv_to_rgb(color_hue, 0.5, 0.9) r2, g2, b2 = colorsys.hsv_to_rgb((color_hue + 0.1) % 1.0, 0.8, 1.0) # Intensity affects darkness/brightness factor = intensity / 100.0 c1 = (int(r1 * 255 * factor), int(g1 * 255 * factor), int(b1 * 255 * factor)) c2 = (int(r2 * 255 * factor), int(g2 * 255 * factor), int(b2 * 255 * factor)) for y in range(height): r = int(c1[0] + (c2[0] - c1[0]) * y / height) g = int(c1[1] + (c2[1] - c1[1]) * y / height) b = int(c1[2] + (c2[2] - c1[2]) * y / height) draw.rectangle([(0, y), (width, y+1)], fill=(r, g, b)) return img def create_mood_board(description, theme_type, intensity): """ Generates an abstract image and a playlist based on inputs. """ # Map theme to hue (0.0 to 1.0) theme_hues = { "Sunset": 0.05, # Orange/Red "Ocean": 0.55, # Cyan/Blue "Forest": 0.3, # Green "Cyberpunk": 0.8, # Purple/Magenta "Noir": 0.0 # Grayscale (handled specially) } base_hue = theme_hues.get(theme_type, 0.0) # Generate Art width, height = 800, 600 img = generate_gradient(width, height, base_hue, intensity) draw = ImageDraw.Draw(img) # Add some abstract shapes for _ in range(5): x0 = random.randint(0, width) y0 = random.randint(0, height) x1 = x0 + random.randint(-100, 100) y1 = y0 + random.randint(-100, 100) alpha = random.randint(50, 150) shape_color = (255, 255, 255) if theme_type == "Noir" else ( int(random.random()*255), int(random.random()*255), int(random.random()*255) ) # Note: PIL doesn't support alpha directly on RGB without a separate layer, # so we just draw solid shapes for simplicity in this demo. draw.ellipse([x0, y0, x1, y1], fill=shape_color) # Add Text Overlay try: # Try to load a nice font, fallback to default if not found font = ImageFont.truetype("arial.ttf", 40) except IOError: font = ImageFont.load_default() text = description.upper() # Calculate text position (centered) bbox = draw.textbbox((0, 0), text, font=font) text_width = bbox[2] - bbox[0] text_height = bbox[3] - bbox[1] position = ((width - text_width) / 2, (height - text_height) / 2) draw.text(position, text, fill="white", font=font, stroke_width=2, stroke_fill="black") # Generate Fake Playlist Data moods = ["Chill", "Energetic", "Melancholic", "Focus"] selected_mood = random.choice(moods) playlist = { "mood": selected_mood, "tracks": [ {"title": f"{theme_type} Vibes Pt.1", "artist": "AI Composer", "duration": "3:45"}, {"title": "Abstract Thoughts", "artist": "Neural Net", "duration": "4:20"}, {"title": "Gradient Sky", "artist": "Pixel Painter", "duration": "2:55"} ] } return img, playlist # --- Gradio 6 Application --- # Gradio 6: gr.Blocks() takes NO parameters with gr.Blocks() as demo: # Header Section gr.Markdown("# 🎨 AI Mood Board Generator") gr.Markdown("Describe a feeling, pick a theme, and generate custom abstract art.") # Required Link gr.HTML('✨ Built with anycoder') with gr.Row(): # Input Column (Sidebar-like) with gr.Column(scale=1): gr.Markdown("### Configuration") desc_input = gr.Textbox( label="Describe your mood", placeholder="e.g. Peaceful morning rain...", lines=2 ) theme_input = gr.Dropdown( choices=["Sunset", "Ocean", "Forest", "Cyberpunk", "Noir"], value="Sunset", label="Color Theme" ) intensity = gr.Slider( minimum=10, maximum=100, value=70, label="Intensity / Brightness", info="Controls the saturation of the colors" ) generate_btn = gr.Button("Generate Mood Board", variant="primary", size="lg") gr.Examples( examples=[ ["Serene Sunday", "Ocean", 80], ["Neon Night Drive", "Cyberpunk", 95], ["Deep Focus", "Noir", 40] ], inputs=[desc_input, theme_input, intensity] ) # Output Column with gr.Column(scale=2): with gr.Tab("Artwork"): output_image = gr.Image(label="Generated Abstract Art", type="pil") with gr.Tab("Details"): output_json = gr.JSON(label="Curated Playlist & Metadata") # Event Listener # Gradio 6: Use api_visibility instead of just api_name generate_btn.click( fn=create_mood_board, inputs=[desc_input, theme_input, intensity], outputs=[output_image, output_json], api_visibility="public" ) # Gradio 6: ALL app parameters go in launch()! # We use the Soft theme with a custom primary hue (Indigo) demo.launch( theme=gr.themes.Soft( primary_hue="indigo", secondary_hue="purple", font=gr.themes.GoogleFont("Inter") ), footer_links=[ {"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}, {"label": "Gradio", "url": "https://www.gradio.app"} ] )