jing96963 commited on
Commit
7fb3256
Β·
verified Β·
1 Parent(s): 546b7d6

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. README.md +6 -7
  2. app.py +111 -0
  3. requirements.txt +6 -0
README.md CHANGED
@@ -1,13 +1,12 @@
1
  ---
2
- title: Image Outpaint
3
- emoji: πŸ’»
4
- colorFrom: indigo
5
- colorTo: purple
6
  sdk: gradio
7
- sdk_version: 6.24.0
8
- python_version: '3.13'
9
  app_file: app.py
10
  pinned: false
 
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: YDWD Image Outpaint
3
+ emoji: πŸ–ΌοΈ
4
+ colorFrom: yellow
5
+ colorTo: green
6
  sdk: gradio
 
 
7
  app_file: app.py
8
  pinned: false
9
+ license: openrail
10
  ---
11
 
12
+ Dedicated masked outpainting backend for AI-IMAGE-YDWD.
app.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+
3
+ import gradio as gr
4
+ import numpy as np
5
+ import spaces
6
+ import torch
7
+ from diffusers import AutoPipelineForInpainting
8
+ from PIL import Image, ImageFilter
9
+
10
+
11
+ MODEL_ID = "diffusers/stable-diffusion-xl-1.0-inpainting-0.1"
12
+ MAX_PIXELS = 1024 * 1024
13
+
14
+ pipe = AutoPipelineForInpainting.from_pretrained(
15
+ MODEL_ID,
16
+ torch_dtype=torch.float16,
17
+ variant="fp16",
18
+ )
19
+ pipe.enable_vae_tiling()
20
+ pipe.enable_vae_slicing()
21
+ pipe.to("cuda")
22
+
23
+
24
+ def _fit_size(width: int, height: int) -> tuple[int, int]:
25
+ scale = min(1.0, (MAX_PIXELS / max(1, width * height)) ** 0.5)
26
+ fitted_w = max(64, int(round(width * scale / 8)) * 8)
27
+ fitted_h = max(64, int(round(height * scale / 8)) * 8)
28
+ return fitted_w, fitted_h
29
+
30
+
31
+ @spaces.GPU(duration=120)
32
+ def outpaint(
33
+ image: Image.Image,
34
+ mask: Image.Image,
35
+ prompt: str,
36
+ negative_prompt: str,
37
+ seed: int,
38
+ steps: int,
39
+ guidance_scale: float,
40
+ ) -> Image.Image:
41
+ if image is None or mask is None:
42
+ raise gr.Error("ιœ€θ¦εŽŸε›Ύε’Œε€–ζ‰©θ’™η‰ˆ")
43
+
44
+ image = image.convert("RGB")
45
+ mask = mask.convert("L")
46
+ original_size = image.size
47
+ run_size = _fit_size(*original_size)
48
+ run_image = image.resize(run_size, Image.Resampling.LANCZOS)
49
+
50
+ # Keep the center protected and soften only the generated-side boundary.
51
+ run_mask = mask.resize(run_size, Image.Resampling.NEAREST)
52
+ run_mask = run_mask.point(lambda value: 255 if value >= 128 else 0)
53
+ run_mask = run_mask.filter(ImageFilter.GaussianBlur(radius=2.0))
54
+
55
+ seed = int(seed) if int(seed) > 0 else random.randint(0, 2**31 - 1)
56
+ generator = torch.Generator(device="cuda").manual_seed(seed)
57
+ result = pipe(
58
+ prompt=prompt,
59
+ negative_prompt=negative_prompt,
60
+ image=run_image,
61
+ mask_image=run_mask,
62
+ width=run_size[0],
63
+ height=run_size[1],
64
+ strength=1.0,
65
+ guidance_scale=float(guidance_scale),
66
+ num_inference_steps=int(steps),
67
+ generator=generator,
68
+ ).images[0]
69
+
70
+ if result.size != original_size:
71
+ result = result.resize(original_size, Image.Resampling.LANCZOS)
72
+ return result
73
+
74
+
75
+ with gr.Blocks(title="YDWD Outpaint") as demo:
76
+ gr.Markdown("# YDWD Outpaint Backend")
77
+ with gr.Row():
78
+ image_input = gr.Image(type="pil", label="Image")
79
+ mask_input = gr.Image(type="pil", image_mode="L", label="Mask")
80
+ output = gr.Image(type="pil", label="Result")
81
+ prompt_input = gr.Textbox(
82
+ value="Seamlessly extend the existing photograph into the masked outer area. Continue the nearby background, lighting, perspective, textures and environment naturally. Keep the original composition and person unchanged.",
83
+ label="Prompt",
84
+ )
85
+ negative_input = gr.Textbox(
86
+ value="duplicate person, repeated person, extra person, duplicated body, repeated image, collage, split image, seam, border, text, watermark, deformed anatomy",
87
+ label="Negative prompt",
88
+ )
89
+ seed_input = gr.Number(value=0, precision=0, label="Seed")
90
+ steps_input = gr.Slider(15, 35, value=24, step=1, label="Steps")
91
+ guidance_input = gr.Slider(3.0, 10.0, value=7.0, step=0.5, label="Guidance")
92
+ run_button = gr.Button("Outpaint", variant="primary")
93
+ run_button.click(
94
+ outpaint,
95
+ inputs=[
96
+ image_input,
97
+ mask_input,
98
+ prompt_input,
99
+ negative_input,
100
+ seed_input,
101
+ steps_input,
102
+ guidance_input,
103
+ ],
104
+ outputs=output,
105
+ api_name="outpaint",
106
+ concurrency_limit=1,
107
+ )
108
+
109
+
110
+ if __name__ == "__main__":
111
+ demo.launch(show_error=True)
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ diffusers>=0.36.0
2
+ transformers>=4.51.0
3
+ accelerate>=1.2.0
4
+ safetensors>=0.4.5
5
+ spaces>=0.40.0
6
+ gradio>=5.0,<7.0