| | import gradio as gr |
| | from diffusers import StableDiffusionPipeline |
| | import torch |
| | import os |
| | from PIL import Image |
| | import warnings |
| |
|
| | warnings.filterwarnings("ignore") |
| |
|
| | MODEL_NAME = "stabilityai/stable-diffusion-2" |
| | CACHE_DIR = "./model_cache" |
| | os.makedirs(CACHE_DIR, exist_ok=True) |
| |
|
| | |
| | pipe = StableDiffusionPipeline.from_pretrained( |
| | MODEL_NAME, |
| | torch_dtype=torch.float32, |
| | cache_dir=CACHE_DIR, |
| | low_cpu_mem_usage=True, |
| | safety_checker=None |
| | ) |
| |
|
| | DISCLAIMER = """ |
| | ⚠️ **Content Warning** |
| | This app generates images based on text prompts. By using this application, you agree to comply with [HuggingFace's Acceptable Use Policy](https://huggingface.co/policies/acceptable-use ). |
| | """ |
| |
|
| | def generate_image(prompt, width, height, num_inference_steps=20, guidance_scale=7.0): |
| | """Generate image with strict validation""" |
| | if not prompt.strip(): |
| | return None, "Error: Prompt cannot be empty" |
| | |
| | try: |
| | |
| | width = int(width) if width else 512 |
| | height = int(height) if height else 512 |
| | |
| | |
| | width = width - (width % 8) |
| | height = height - (height % 8) |
| | |
| | with torch.inference_mode(): |
| | |
| | result = pipe( |
| | prompt=str(prompt), |
| | width=int(width), |
| | height=int(height), |
| | num_inference_steps=int(num_inference_steps), |
| | guidance_scale=float(guidance_scale) |
| | ) |
| | |
| | |
| | if not hasattr(result, "images") or not isinstance(result.images, list): |
| | return None, f"Invalid pipeline output format: {type(result)}" |
| | |
| | if len(result.images) == 0: |
| | return None, "Pipeline returned empty image list" |
| | |
| | if result.images[0] is None: |
| | return None, "Pipeline returned None image" |
| | |
| | return result.images[0].convert("RGB"), f"Success ({width}x{height})" |
| | |
| | except Exception as e: |
| | return None, f"Generation Error: {str(e)}" |
| |
|
| | |
| | ASPECT_RATIOS = { |
| | "Square (512x512)": (512, 512), |
| | "Portrait (512x768)": (512, 768), |
| | "Landscape (768x512)": (768, 512), |
| | "Phone (384x832)": (384, 832), |
| | "Custom": None |
| | } |
| |
|
| | with gr.Blocks(theme="soft", css=".disclaimer {color: #FF4B2B; font-size: 0.9em;}") as demo: |
| | gr.Markdown("# 🔞 Text-to-Image Generator\n" + DISCLAIMER) |
| | |
| | with gr.Row(): |
| | with gr.Column(): |
| | prompt = gr.Textbox( |
| | label="Prompt", |
| | placeholder="Describe your image...", |
| | lines=3 |
| | ) |
| | with gr.Row(): |
| | width = gr.Number(value=512, label="Width", interactive=True) |
| | height = gr.Number(value=512, label="Height", interactive=True) |
| | aspect_ratio = gr.Dropdown( |
| | choices=list(ASPECT_RATIOS.keys()), |
| | value="Square (512x512)", |
| | label="Aspect Ratio" |
| | ) |
| | generate_btn = gr.Button("Generate Image", variant="primary") |
| | |
| | with gr.Column(): |
| | output_image = gr.Image(label="Result", interactive=False) |
| | error_msg = gr.Textbox(label="Status", value="Ready", interactive=False) |
| | |
| | def update_dimensions(choice): |
| | if choice == "Custom": |
| | return [gr.Number(value=512, interactive=True), gr.Number(value=512, interactive=True)] |
| | else: |
| | w, h = ASPECT_RATIOS[choice] |
| | return [gr.Number(value=w, interactive=True), gr.Number(value=h, interactive=True)] |
| | |
| | aspect_ratio.change(fn=update_dimensions, inputs=[aspect_ratio], outputs=[width, height]) |
| | |
| | generate_btn.click( |
| | fn=generate_image, |
| | inputs=[prompt, width, height], |
| | outputs=[output_image, error_msg] |
| | ) |
| |
|
| | if __name__ == "__main__": |
| | demo.launch() |