Spaces:
Sleeping
Sleeping
| # app.py | |
| import gradio as gr | |
| import torch | |
| from diffusers import AutoPipelineForInpainting | |
| from PIL import Image | |
| import time | |
| # --- Model Loading (CPU Version) --- | |
| print("Loading model on CPU... This may take several minutes.") | |
| # This is the corrected line that fixes the error. | |
| pipe = AutoPipelineForInpainting.from_pretrained( | |
| "stabilityai/stable-diffusion-2-inpainting", | |
| torch_dtype=torch.float32, # Use float32 for broad CPU compatibility | |
| safety_checker=None # Explicitly disable the safety checker to prevent loading errors | |
| ) | |
| print("Model loaded successfully.") | |
| # --- Default "Magic" Prompts --- | |
| DEFAULT_PROMPT = "photorealistic, 4k, ultra high quality, sharp focus, masterpiece, high detail, professional photo" | |
| DEFAULT_NEGATIVE_PROMPT = "blurry, pixelated, distorted, deformed, ugly, disfigured, cartoon, anime, low quality, watermark, text" | |
| # --- The Inpainting Function --- | |
| def inpaint_image(input_dict, user_prompt, guidance_scale, num_steps, progress=gr.Progress()): | |
| image = input_dict["image"].convert("RGB") | |
| mask_image = input_dict["mask"].convert("RGB") | |
| if user_prompt and user_prompt.strip(): | |
| prompt = user_prompt | |
| negative_prompt = DEFAULT_NEGATIVE_PROMPT | |
| print(f"Using custom prompt: '{prompt}'") | |
| else: | |
| prompt = DEFAULT_PROMPT | |
| negative_prompt = DEFAULT_NEGATIVE_PROMPT | |
| print(f"User prompt is empty. Using default 'General Fix' prompt.") | |
| print(f"Starting inpainting on CPU...") | |
| start_time = time.time() | |
| def progress_callback(step, timestep, latents): | |
| progress(step / int(num_steps), desc=f"Running step {step}/{int(num_steps)}") | |
| result_image = pipe( | |
| prompt=prompt, | |
| image=image, | |
| mask_image=mask_image, | |
| negative_prompt=negative_prompt, | |
| guidance_scale=guidance_scale, | |
| num_inference_steps=int(num_steps), | |
| callback_steps=1, | |
| callback=progress_callback, | |
| ).images[0] | |
| end_time = time.time() | |
| print(f"Inpainting finished in {end_time - start_time:.2f} seconds.") | |
| return result_image | |
| # --- Gradio User Interface --- | |
| with gr.Blocks(theme=gr.themes.Soft()) as demo: | |
| gr.Markdown( | |
| """ | |
| # 🎨 AI Image Fixer | |
| **How to use:** | |
| 1. Upload an image. | |
| 2. Use the brush to **paint over the area you want to fix**. | |
| 3. **(Optional)** For precise control, write a custom prompt describing the fix. | |
| 4. **(Easy Mode)** Or, just leave the prompt box empty for a general quality improvement. | |
| 5. Click "Fix It!" | |
| """ | |
| ) | |
| gr.Warning( | |
| "⚠️ This Space is running on a free CPU. " | |
| "Image generation will be VERY SLOW (expect 5-20 minutes). " | |
| "A progress bar will show the status below the button. Please be patient!" | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| input_image = gr.Image(label="1. Upload & Mask Image", source="upload", tool="brush", type="pil") | |
| prompt_textbox = gr.Textbox(label="2. Describe Your Fix (Optional)", placeholder="Leave empty for a general fix, or type e.g., 'a perfect human hand'") | |
| with gr.Accordion("Advanced Settings", open=False): | |
| guidance_scale = gr.Slider(minimum=0, maximum=20, value=8.0, label="Guidance Scale") | |
| num_steps = gr.Slider(minimum=10, maximum=50, step=1, value=25, label="Inference Steps") | |
| with gr.Column(scale=1): | |
| output_image = gr.Image(label="Result", type="pil") | |
| submit_button = gr.Button("Fix It!", variant="primary") | |
| submit_button.click( | |
| fn=inpaint_image, | |
| inputs=[input_image, prompt_textbox, guidance_scale, num_steps], | |
| outputs=output_image | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |