import gradio as gr from diffusers import StableDiffusionPipeline, DDIMScheduler import torch from PIL import ImageEnhance, Image import numpy as np import spaces # For using ZeroGPU decorator # Load Stable Diffusion pipeline with efficient defaults model_id = "CompVis/stable-diffusion-v1-4" default_scheduler = DDIMScheduler.from_pretrained(model_id, subfolder="scheduler") device = "cuda" if torch.cuda.is_available() else "cpu" torch_dtype = torch.float16 if device == "cuda" else torch.float32 pipe = StableDiffusionPipeline.from_pretrained(model_id, scheduler=default_scheduler, torch_dtype=torch_dtype).to(device) # Scheduler options (setting DDIM as the default for speed) schedulers = { "High-Definition & Fast (DDIM) - Good quality with fastest speed": DDIMScheduler, "Photo-Realistic (PNDM) - Best for realistic details, moderate speed": PNDMScheduler, "Artistic & Imaginative (Euler Ancestral) - Good for creative scenes, moderate speed": EulerAncestralDiscreteScheduler, } # Main image generation function with 60-second GPU duration limit @spaces.GPU(duration=60) def generate_image(prompt, use_categories, genre, style, theme, lighting, scheduler_choice, quality, size): # Check if additional categories should be added to the prompt if use_categories: prompt_text = ( f"{prompt.strip()} in a {genre.lower()} wallpaper style, " f"with {style.lower()} visuals, focusing on a {theme.lower()} theme " f"and {lighting.lower()} lighting." ) else: prompt_text = prompt.strip() # Set the scheduler based on user choice scheduler = schedulers[scheduler_choice].from_pretrained(model_id, subfolder="scheduler") pipe.scheduler = scheduler # Set output size based on selection image_size = (512, 512) if size == "Profile Picture" else (512, 512) # Using smaller size for faster generation # Generate image with specified quality and size with torch.no_grad(): image = pipe(prompt_text, num_inference_steps=quality, guidance_scale=7.5).images[0] image = image.resize(image_size) # Resize image to fit selected dimensions return np.array(image) # Return as NumPy array for Gradio # Post-processing function for brightness and contrast def adjust_brightness_contrast(image, brightness, contrast): image = Image.fromarray(image.astype('uint8'), 'RGB') image = ImageEnhance.Brightness(image).enhance(brightness) image = ImageEnhance.Contrast(image).enhance(contrast) return np.array(image) # Warning function for high-quality settings def show_warning(quality): if quality > 40: # Lower threshold for warning return "⚠️ High Quality: This may slow down generation. Consider using values below 40 for faster results." return "" # Build Gradio Interface with adjusted defaults with gr.Blocks() as demo: gr.Markdown("# ✨ AI-Powered Wallpaper/Profile Picture Generator\n🖼️ A tool to generate and fine-tune AI-created wallpapers and profile pictures with adjustable styles and effects.") # Image Generation Section with gr.Tab("Image Generator"): gr.Markdown("## Generate an Image") with gr.Row(): with gr.Column(): custom_prompt = gr.Textbox(label="Custom Prompt", placeholder="Describe your image (e.g., 'A forest at sunset')") # Toggle for using additional categories use_categories = gr.Checkbox(label="Enable Advanced Settings (Genre, Style, Theme, Lighting)", value=False) # Additional categories, hidden by default and shown only if use_categories is checked with gr.Accordion("Advanced Settings", open=False): genre = gr.Dropdown(["Futuristic", "Nature", "Abstract", "Fantasy", "Sci-Fi", "Cyberpunk"], label="Genre") style = gr.Dropdown(["Realistic", "Surreal", "Digital Art", "Cartoon", "Photorealistic"], label="Style") theme = gr.Dropdown(["Landscape", "Portrait", "Abstract Patterns", "Architecture"], label="Theme") lighting = gr.Dropdown(["Warm", "Cool", "Cinematic", "Soft", "Neon"], label="Lighting") # Reduced quality for faster generation quality = gr.Slider(20, 80, value=30, step=10, label="Image Quality", info="Lower values for faster generation.") warning_message = gr.Markdown("") # Scheduler selection with default option as DDIM for speed scheduler_choice = gr.Dropdown( [ "High-Definition & Fast (DDIM) - Good quality with fastest speed", "Photo-Realistic (PNDM) - Best for realistic details, moderate speed", "Artistic & Imaginative (Euler Ancestral) - Good for creative scenes, moderate speed" ], label="Artistic Style & Speed", value="High-Definition & Fast (DDIM) - Good quality with fastest speed" ) size = gr.Dropdown(["Profile Picture", "Wallpaper"], label="Image Size", value="Profile Picture") generate_button = gr.Button("Generate Image") with gr.Column(): generated_image = gr.Image(label="Generated Image", interactive=False) # Display warning message for high-quality settings quality.change(show_warning, inputs=[quality], outputs=warning_message) # Bind the generate function to the generate button generate_button.click( fn=generate_image, inputs=[custom_prompt, use_categories, genre, style, theme, lighting, scheduler_choice, quality, size], outputs=generated_image ) # Post-Processing Section with gr.Tab("Edit Generated Image"): gr.Markdown("## Adjust Brightness & Contrast") with gr.Row(): with gr.Column(): brightness_slider = gr.Slider(0.5, 2.0, value=1.0, label="Brightness") contrast_slider = gr.Slider(0.5, 2.0, value=1.0, label="Contrast") apply_adjustments = gr.Button("Apply Adjustments") with gr.Column(): output_image = gr.Image(label="Adjusted Image", interactive=False) # Bind the brightness and contrast adjustment function to the Apply Adjustments button apply_adjustments.click( fn=adjust_brightness_contrast, inputs=[generated_image, brightness_slider, contrast_slider], outputs=output_image ) # Launch with a public shareable link demo.launch(share=True)