Fabrice-TIERCELIN commited on
Commit
a6a99b6
1 Parent(s): 36ff3ea

Upgrade to 4.41.0

Browse files
Files changed (2) hide show
  1. README.md +22 -22
  2. app.py +458 -412
README.md CHANGED
@@ -1,23 +1,23 @@
1
- ---
2
- title: Inpaint SDXL (any size)
3
- emoji: ↕️
4
- colorFrom: blue
5
- colorTo: purple
6
- tags:
7
- - Image-to-Image
8
- - Image-2-Image
9
- - Img-to-Img
10
- - Img-2-Img
11
- - SDXL
12
- - Stable Diffusion
13
- - language models
14
- - LLMs
15
- sdk: gradio
16
- sdk_version: 3.48.0
17
- app_file: app.py
18
- pinned: false
19
- license: mit
20
- short_description: Modifies one detail of your image, at any resolution, freely
21
- ---
22
-
23
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+ ---
2
+ title: Inpaint SDXL (any size)
3
+ emoji: ↕️
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ tags:
7
+ - Image-to-Image
8
+ - Image-2-Image
9
+ - Img-to-Img
10
+ - Img-2-Img
11
+ - SDXL
12
+ - Stable Diffusion
13
+ - language models
14
+ - LLMs
15
+ sdk: gradio
16
+ sdk_version: 4.41.0
17
+ app_file: app.py
18
+ pinned: false
19
+ license: mit
20
+ short_description: Modifies one detail of your image, at any resolution, freely
21
+ ---
22
+
23
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py CHANGED
@@ -1,413 +1,459 @@
1
- import gradio as gr
2
- import numpy as np
3
- import time
4
- import math
5
- import random
6
- import imageio
7
- import torch
8
- import spaces
9
-
10
- from diffusers import StableDiffusionXLInpaintPipeline
11
- from PIL import Image, ImageFilter
12
-
13
- max_64_bit_int = 2**63 - 1
14
-
15
- if torch.cuda.is_available():
16
- device = "cuda"
17
- floatType = torch.float16
18
- variant = "fp16"
19
- else:
20
- device = "cpu"
21
- floatType = torch.float32
22
- variant = None
23
-
24
- pipe = StableDiffusionXLInpaintPipeline.from_pretrained("diffusers/stable-diffusion-xl-1.0-inpainting-0.1", torch_dtype = floatType, variant = variant)
25
- pipe = pipe.to(device)
26
-
27
- def update_seed(is_randomize_seed, seed):
28
- if is_randomize_seed:
29
- return random.randint(0, max_64_bit_int)
30
- return seed
31
-
32
- def toggle_debug(is_debug_mode):
33
- return [gr.update(visible = is_debug_mode)] * 2
34
-
35
- def check(
36
- source_img,
37
- prompt,
38
- uploaded_mask,
39
- negative_prompt,
40
- num_inference_steps,
41
- guidance_scale,
42
- image_guidance_scale,
43
- strength,
44
- denoising_steps,
45
- is_randomize_seed,
46
- seed,
47
- debug_mode,
48
- progress = gr.Progress()
49
- ):
50
- if source_img is None:
51
- raise gr.Error("Please provide an image.")
52
-
53
- if prompt is None or prompt == "":
54
- raise gr.Error("Please provide a prompt input.")
55
-
56
- @spaces.GPU(duration=420)
57
- def inpaint(
58
- source_img,
59
- prompt,
60
- uploaded_mask,
61
- negative_prompt,
62
- num_inference_steps,
63
- guidance_scale,
64
- image_guidance_scale,
65
- strength,
66
- denoising_steps,
67
- is_randomize_seed,
68
- seed,
69
- debug_mode,
70
- progress = gr.Progress()
71
- ):
72
- check(
73
- source_img,
74
- prompt,
75
- uploaded_mask,
76
- negative_prompt,
77
- num_inference_steps,
78
- guidance_scale,
79
- image_guidance_scale,
80
- strength,
81
- denoising_steps,
82
- is_randomize_seed,
83
- seed,
84
- debug_mode
85
- )
86
- start = time.time()
87
- progress(0, desc = "Preparing data...")
88
-
89
- if negative_prompt is None:
90
- negative_prompt = ""
91
-
92
- if num_inference_steps is None:
93
- num_inference_steps = 25
94
-
95
- if guidance_scale is None:
96
- guidance_scale = 7
97
-
98
- if image_guidance_scale is None:
99
- image_guidance_scale = 1.1
100
-
101
- if strength is None:
102
- strength = 0.99
103
-
104
- if denoising_steps is None:
105
- denoising_steps = 1000
106
-
107
- if seed is None:
108
- seed = random.randint(0, max_64_bit_int)
109
-
110
- random.seed(seed)
111
- #pipe = pipe.manual_seed(seed)
112
-
113
- input_image = source_img["image"].convert("RGB")
114
-
115
- original_height, original_width, original_channel = np.array(input_image).shape
116
- output_width = original_width
117
- output_height = original_height
118
-
119
- if uploaded_mask is None:
120
- mask_image = source_img["mask"].convert("RGB")
121
- else:
122
- mask_image = uploaded_mask.convert("RGB")
123
- mask_image = mask_image.resize((original_width, original_height))
124
-
125
- # Limited to 1 million pixels
126
- if 1024 * 1024 < output_width * output_height:
127
- factor = ((1024 * 1024) / (output_width * output_height))**0.5
128
- process_width = math.floor(output_width * factor)
129
- process_height = math.floor(output_height * factor)
130
-
131
- limitation = " Due to technical limitation, the image have been downscaled and then upscaled.";
132
- else:
133
- process_width = output_width
134
- process_height = output_height
135
-
136
- limitation = "";
137
-
138
- # Width and height must be multiple of 8
139
- if (process_width % 8) != 0 or (process_height % 8) != 0:
140
- if ((process_width - (process_width % 8) + 8) * (process_height - (process_height % 8) + 8)) <= (1024 * 1024):
141
- process_width = process_width - (process_width % 8) + 8
142
- process_height = process_height - (process_height % 8) + 8
143
- elif (process_height % 8) <= (process_width % 8) and ((process_width - (process_width % 8) + 8) * process_height) <= (1024 * 1024):
144
- process_width = process_width - (process_width % 8) + 8
145
- process_height = process_height - (process_height % 8)
146
- elif (process_width % 8) <= (process_height % 8) and (process_width * (process_height - (process_height % 8) + 8)) <= (1024 * 1024):
147
- process_width = process_width - (process_width % 8)
148
- process_height = process_height - (process_height % 8) + 8
149
- else:
150
- process_width = process_width - (process_width % 8)
151
- process_height = process_height - (process_height % 8)
152
-
153
- progress(None, desc = "Processing...")
154
- output_image = pipe(
155
- seeds = [seed],
156
- width = process_width,
157
- height = process_height,
158
- prompt = prompt,
159
- negative_prompt = negative_prompt,
160
- image = input_image,
161
- mask_image = mask_image,
162
- num_inference_steps = num_inference_steps,
163
- guidance_scale = guidance_scale,
164
- image_guidance_scale = image_guidance_scale,
165
- strength = strength,
166
- denoising_steps = denoising_steps,
167
- show_progress_bar = True
168
- ).images[0]
169
-
170
- if limitation != "":
171
- output_image = output_image.resize((output_width, output_height))
172
-
173
- if debug_mode == False:
174
- input_image = None
175
- mask_image = None
176
-
177
- end = time.time()
178
- secondes = int(end - start)
179
- minutes = math.floor(secondes / 60)
180
- secondes = secondes - (minutes * 60)
181
- hours = math.floor(minutes / 60)
182
- minutes = minutes - (hours * 60)
183
- return [
184
- output_image,
185
- ("Start again to get a different result. " if is_randomize_seed else "") + "The image has been generated in " + ((str(hours) + " h, ") if hours != 0 else "") + ((str(minutes) + " min, ") if hours != 0 or minutes != 0 else "") + str(secondes) + " sec." + limitation,
186
- input_image,
187
- mask_image
188
- ]
189
-
190
- with gr.Blocks() as interface:
191
- gr.HTML(
192
- """
193
- <h1 style="text-align: center;">Inpaint</h1>
194
- <p style="text-align: center;">Modifies one detail of your image, at any resolution, freely, without account, without watermark, without installation, which can be downloaded</p>
195
- <br/>
196
- <br/>
197
- ✨ Powered by <i>SDXL 1.0</i> artificial intellingence. For illustration purpose, not information purpose. The new content is not based on real information but imagination.
198
- <br/>
199
- <ul>
200
- <li>To change the <b>view angle</b> of your image, I recommend to use <i>Zero123</i>,</li>
201
- <li>To <b>upscale</b> your image, I recommend to use <i><a href="https://huggingface.co/spaces/Fabrice-TIERCELIN/SUPIR">SUPIR</a></i>,</li>
202
- <li>To <b>slightly change</b> your image, I recommend to use <i>Image-to-Image SDXL</i>,</li>
203
- <li>If you need to enlarge the <b>viewpoint</b> of your image, I recommend you to use <i>Uncrop</i>,</li>
204
- <li>To remove the <b>background</b> of your image, I recommend to use <i>BRIA</i>,</li>
205
- <li>To make a <b>tile</b> of your image, I recommend to use <i>Make My Image Tile</i>,</li>
206
- <li>To modify <b>anything else</b> on your image, I recommend to use <i>Instruct Pix2Pix</i>.</li>
207
- </ul>
208
- <br/>
209
- """ + ("🏃‍♀️ Estimated time: few minutes." if torch.cuda.is_available() else "🐌 Slow process... ~1 hour.") + """
210
- Your computer must not enter into standby mode.<br/>You can duplicate this space on a free account, it's designed to work on CPU, GPU and ZeroGPU.<br/>
211
- <a href='https://huggingface.co/spaces/Fabrice-TIERCELIN/Inpaint?duplicate=true'><img src='https://img.shields.io/badge/-Duplicate%20Space-blue?labelColor=white&style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAP5JREFUOE+lk7FqAkEURY+ltunEgFXS2sZGIbXfEPdLlnxJyDdYB62sbbUKpLbVNhyYFzbrrA74YJlh9r079973psed0cvUD4A+4HoCjsA85X0Dfn/RBLBgBDxnQPfAEJgBY+A9gALA4tcbamSzS4xq4FOQAJgCDwV2CPKV8tZAJcAjMMkUe1vX+U+SMhfAJEHasQIWmXNN3abzDwHUrgcRGmYcgKe0bxrblHEB4E/pndMazNpSZGcsZdBlYJcEL9Afo75molJyM2FxmPgmgPqlWNLGfwZGG6UiyEvLzHYDmoPkDDiNm9JR9uboiONcBXrpY1qmgs21x1QwyZcpvxt9NS09PlsPAAAAAElFTkSuQmCC&logoWidth=14'></a>
212
- <br/>
213
- ⚖️ You can use, modify and share the generated images but not for commercial uses.
214
-
215
- """
216
- )
217
- with gr.Column():
218
- source_img = gr.Image(label = "Your image", source = "upload", tool = "sketch", type = "pil")
219
- prompt = gr.Textbox(label = "Prompt", info = "Describe the subject, the background and the style of image; 77 token limit", placeholder = "Describe what you want to see in the entire image", lines = 2)
220
- with gr.Accordion("Upload a mask", open = False):
221
- uploaded_mask = gr.Image(label = "Already made mask (black pixels will be preserved, white pixels will be redrawn)", source = "upload", type = "pil")
222
- with gr.Accordion("Advanced options", open = False):
223
- negative_prompt = gr.Textbox(label = "Negative prompt", placeholder = "Describe what you do NOT want to see in the entire image", value = "Ugly, malformed, noise, blur, watermark")
224
- num_inference_steps = gr.Slider(minimum = 10, maximum = 100, value = 25, step = 1, label = "Number of inference steps", info = "lower=faster, higher=image quality")
225
- guidance_scale = gr.Slider(minimum = 1, maximum = 13, value = 7, step = 0.1, label = "Classifier-Free Guidance Scale", info = "lower=image quality, higher=follow the prompt")
226
- image_guidance_scale = gr.Slider(minimum = 1, value = 1.1, step = 0.1, label = "Image Guidance Scale", info = "lower=image quality, higher=follow the image")
227
- strength = gr.Slider(value = 0.99, minimum = 0.01, maximum = 1.0, step = 0.01, label = "Strength", info = "lower=follow the original area, higher=redraw from scratch")
228
- denoising_steps = gr.Number(minimum = 0, value = 1000, step = 1, label = "Denoising", info = "lower=irrelevant result, higher=relevant result")
229
- randomize_seed = gr.Checkbox(label = "\U0001F3B2 Randomize seed", value = True, info = "If checked, result is always different")
230
- seed = gr.Slider(minimum = 0, maximum = max_64_bit_int, step = 1, randomize = True, label = "Seed")
231
- debug_mode = gr.Checkbox(label = "Debug mode", value = False, info = "Show intermediate results")
232
-
233
- submit = gr.Button("🚀 Inpaint", variant = "primary")
234
-
235
- inpainted_image = gr.Image(label = "Inpainted image")
236
- information = gr.HTML()
237
- original_image = gr.Image(label = "Original image", visible = False)
238
- mask_image = gr.Image(label = "Mask image", visible = False)
239
-
240
- submit.click(update_seed, inputs = [
241
- randomize_seed, seed
242
- ], outputs = [
243
- seed
244
- ], queue = False, show_progress = False).then(toggle_debug, debug_mode, [
245
- original_image,
246
- mask_image
247
- ], queue = False, show_progress = False).then(check, inputs = [
248
- source_img,
249
- prompt,
250
- uploaded_mask,
251
- negative_prompt,
252
- num_inference_steps,
253
- guidance_scale,
254
- image_guidance_scale,
255
- strength,
256
- denoising_steps,
257
- randomize_seed,
258
- seed,
259
- debug_mode
260
- ], outputs = [], queue = False, show_progress = False).success(inpaint, inputs = [
261
- source_img,
262
- prompt,
263
- uploaded_mask,
264
- negative_prompt,
265
- num_inference_steps,
266
- guidance_scale,
267
- image_guidance_scale,
268
- strength,
269
- denoising_steps,
270
- randomize_seed,
271
- seed,
272
- debug_mode
273
- ], outputs = [
274
- inpainted_image,
275
- information,
276
- original_image,
277
- mask_image
278
- ], scroll_to_output = True)
279
-
280
- gr.Examples(
281
- fn = inpaint,
282
- inputs = [
283
- source_img,
284
- prompt,
285
- uploaded_mask,
286
- negative_prompt,
287
- num_inference_steps,
288
- guidance_scale,
289
- image_guidance_scale,
290
- strength,
291
- denoising_steps,
292
- randomize_seed,
293
- seed,
294
- debug_mode
295
- ],
296
- outputs = [
297
- inpainted_image,
298
- information,
299
- original_image,
300
- mask_image
301
- ],
302
- examples = [
303
- [
304
- "./Examples/Example1.png",
305
- "A deer, in a forest landscape, ultrarealistic, realistic, photorealistic, 8k",
306
- "./Examples/Mask1.webp",
307
- "Ugly, malformed, painting, drawing, cartoon, anime, 3d, noise, blur, watermark",
308
- 25,
309
- 7,
310
- 1.1,
311
- 0.99,
312
- 1000,
313
- False,
314
- 42,
315
- False
316
- ],
317
- [
318
- "./Examples/Example3.jpg",
319
- "An angry old woman, ultrarealistic, realistic, photorealistic, 8k",
320
- "./Examples/Mask3.gif",
321
- "Ugly, malformed, painting, drawing, cartoon, anime, 3d, noise, blur, watermark",
322
- 25,
323
- 7,
324
- 1.5,
325
- 0.99,
326
- 1000,
327
- False,
328
- 42,
329
- False
330
- ],
331
- [
332
- "./Examples/Example4.gif",
333
- "A laptop, ultrarealistic, realistic, photorealistic, 8k",
334
- "./Examples/Mask4.bmp",
335
- "Ugly, malformed, painting, drawing, cartoon, anime, 3d, noise, blur, watermark",
336
- 25,
337
- 7,
338
- 1.1,
339
- 0.99,
340
- 1000,
341
- False,
342
- 42,
343
- False
344
- ],
345
- [
346
- "./Examples/Example5.bmp",
347
- "A sand castle, ultrarealistic, realistic, photorealistic, 8k",
348
- "./Examples/Mask5.png",
349
- "Ugly, malformed, painting, drawing, cartoon, anime, 3d, noise, blur, watermark",
350
- 50,
351
- 7,
352
- 1.5,
353
- 0.5,
354
- 1000,
355
- False,
356
- 42,
357
- False
358
- ],
359
- [
360
- "./Examples/Example2.webp",
361
- "A cat, ultrarealistic, realistic, photorealistic, 8k",
362
- "./Examples/Mask2.png",
363
- "Ugly, malformed, painting, drawing, cartoon, anime, 3d, noise, blur, watermark",
364
- 25,
365
- 7,
366
- 1.1,
367
- 0.99,
368
- 1000,
369
- False,
370
- 42,
371
- False
372
- ],
373
- ],
374
- cache_examples = False,
375
- )
376
-
377
- gr.Markdown(
378
- """
379
- ## How to prompt your image
380
-
381
- To easily read your prompt, start with the subject, then describ the pose or action, then secondary elements, then the background, then the graphical style, then the image quality:
382
- ```
383
- A Vietnamese woman, red clothes, walking, smilling, in the street, a car on the left, in a modern city, photorealistic, 8k
384
- ```
385
-
386
- You can use round brackets to increase the importance of a part:
387
- ```
388
- A Vietnamese woman, (red clothes), walking, smilling, in the street, a car on the left, in a modern city, photorealistic, 8k
389
- ```
390
-
391
- You can use several levels of round brackets to even more increase the importance of a part:
392
- ```
393
- A Vietnamese woman, ((red clothes)), (walking), smilling, in the street, a car on the left, in a modern city, photorealistic, 8k
394
- ```
395
-
396
- You can use number instead of several round brackets:
397
- ```
398
- A Vietnamese woman, (red clothes:1.5), (walking), smilling, in the street, a car on the left, in a modern city, photorealistic, 8k
399
- ```
400
-
401
- You can do the same thing with square brackets to decrease the importance of a part:
402
- ```
403
- A [Vietnamese] woman, (red clothes:1.5), (walking), smilling, in the street, a car on the left, in a modern city, photorealistic, 8k
404
- ```
405
-
406
- To easily read your negative prompt, organize it the same way as your prompt (not important for the AI):
407
- ```
408
- man, boy, hat, running, tree, bicycle, forest, drawing, painting, cartoon, 3d, monochrome, blurry, noisy, bokeh
409
- ```
410
- """
411
- )
412
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
  interface.queue().launch()
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import time
4
+ import math
5
+ import random
6
+ import imageio
7
+ import torch
8
+ import spaces
9
+
10
+ from diffusers import StableDiffusionXLInpaintPipeline
11
+ from PIL import Image, ImageFilter, ImageEnhance
12
+ import PIL.ImageOps
13
+
14
+ max_64_bit_int = 2**63 - 1
15
+
16
+ if torch.cuda.is_available():
17
+ device = "cuda"
18
+ floatType = torch.float16
19
+ variant = "fp16"
20
+ else:
21
+ device = "cpu"
22
+ floatType = torch.float32
23
+ variant = None
24
+
25
+ pipe = StableDiffusionXLInpaintPipeline.from_pretrained("diffusers/stable-diffusion-xl-1.0-inpainting-0.1", torch_dtype = floatType, variant = variant)
26
+ pipe = pipe.to(device)
27
+
28
+ def update_seed(is_randomize_seed, seed):
29
+ if is_randomize_seed:
30
+ return random.randint(0, max_64_bit_int)
31
+ return seed
32
+
33
+ def toggle_debug(is_debug_mode):
34
+ return [gr.update(visible = is_debug_mode)] * 2
35
+
36
+ def check(
37
+ source_img,
38
+ prompt,
39
+ uploaded_mask,
40
+ negative_prompt,
41
+ num_inference_steps,
42
+ guidance_scale,
43
+ image_guidance_scale,
44
+ strength,
45
+ denoising_steps,
46
+ is_randomize_seed,
47
+ seed,
48
+ debug_mode,
49
+ progress = gr.Progress()
50
+ ):
51
+ if source_img is None:
52
+ raise gr.Error("Please provide an image.")
53
+
54
+ if prompt is None or prompt == "":
55
+ raise gr.Error("Please provide a prompt input.")
56
+
57
+ def inpaint(
58
+ source_img,
59
+ prompt,
60
+ uploaded_mask,
61
+ negative_prompt,
62
+ num_inference_steps,
63
+ guidance_scale,
64
+ image_guidance_scale,
65
+ strength,
66
+ denoising_steps,
67
+ is_randomize_seed,
68
+ seed,
69
+ debug_mode,
70
+ progress = gr.Progress()
71
+ ):
72
+ check(
73
+ source_img,
74
+ prompt,
75
+ uploaded_mask,
76
+ negative_prompt,
77
+ num_inference_steps,
78
+ guidance_scale,
79
+ image_guidance_scale,
80
+ strength,
81
+ denoising_steps,
82
+ is_randomize_seed,
83
+ seed,
84
+ debug_mode
85
+ )
86
+ start = time.time()
87
+ progress(0, desc = "Preparing data...")
88
+
89
+ if negative_prompt is None:
90
+ negative_prompt = ""
91
+
92
+ if num_inference_steps is None:
93
+ num_inference_steps = 25
94
+
95
+ if guidance_scale is None:
96
+ guidance_scale = 7
97
+
98
+ if image_guidance_scale is None:
99
+ image_guidance_scale = 1.1
100
+
101
+ if strength is None:
102
+ strength = 0.99
103
+
104
+ if denoising_steps is None:
105
+ denoising_steps = 1000
106
+
107
+ if seed is None:
108
+ seed = random.randint(0, max_64_bit_int)
109
+
110
+ random.seed(seed)
111
+ #pipe = pipe.manual_seed(seed)
112
+
113
+ input_image = source_img["background"].convert("RGB")
114
+
115
+ original_height, original_width, original_channel = np.array(input_image).shape
116
+ output_width = original_width
117
+ output_height = original_height
118
+
119
+ if uploaded_mask is None:
120
+ mask_image = source_img["layers"][0].convert("RGB")
121
+ else:
122
+ mask_image = uploaded_mask.convert("RGB")
123
+ mask_image = mask_image.resize((original_width, original_height))
124
+
125
+ # Limited to 1 million pixels
126
+ if 1024 * 1024 < output_width * output_height:
127
+ factor = ((1024 * 1024) / (output_width * output_height))**0.5
128
+ process_width = math.floor(output_width * factor)
129
+ process_height = math.floor(output_height * factor)
130
+
131
+ limitation = " Due to technical limitation, the image have been downscaled and then upscaled.";
132
+ else:
133
+ process_width = output_width
134
+ process_height = output_height
135
+
136
+ limitation = "";
137
+
138
+ # Width and height must be multiple of 8
139
+ if (process_width % 8) != 0 or (process_height % 8) != 0:
140
+ if ((process_width - (process_width % 8) + 8) * (process_height - (process_height % 8) + 8)) <= (1024 * 1024):
141
+ process_width = process_width - (process_width % 8) + 8
142
+ process_height = process_height - (process_height % 8) + 8
143
+ elif (process_height % 8) <= (process_width % 8) and ((process_width - (process_width % 8) + 8) * process_height) <= (1024 * 1024):
144
+ process_width = process_width - (process_width % 8) + 8
145
+ process_height = process_height - (process_height % 8)
146
+ elif (process_width % 8) <= (process_height % 8) and (process_width * (process_height - (process_height % 8) + 8)) <= (1024 * 1024):
147
+ process_width = process_width - (process_width % 8)
148
+ process_height = process_height - (process_height % 8) + 8
149
+ else:
150
+ process_width = process_width - (process_width % 8)
151
+ process_height = process_height - (process_height % 8)
152
+
153
+ progress(None, desc = "Processing...")
154
+ output_image = inpaint_on_gpu(
155
+ seed,
156
+ process_width,
157
+ process_height,
158
+ prompt,
159
+ negative_prompt,
160
+ input_image,
161
+ mask_image,
162
+ num_inference_steps,
163
+ guidance_scale,
164
+ image_guidance_scale,
165
+ strength,
166
+ denoising_steps
167
+ )
168
+
169
+ if limitation != "":
170
+ output_image = output_image.resize((output_width, output_height))
171
+
172
+ if debug_mode == False:
173
+ input_image = None
174
+ mask_image = None
175
+
176
+ end = time.time()
177
+ secondes = int(end - start)
178
+ minutes = math.floor(secondes / 60)
179
+ secondes = secondes - (minutes * 60)
180
+ hours = math.floor(minutes / 60)
181
+ minutes = minutes - (hours * 60)
182
+ return [
183
+ output_image,
184
+ ("Start again to get a different result. " if is_randomize_seed else "") + "The image has been generated in " + ((str(hours) + " h, ") if hours != 0 else "") + ((str(minutes) + " min, ") if hours != 0 or minutes != 0 else "") + str(secondes) + " sec." + limitation,
185
+ input_image,
186
+ mask_image
187
+ ]
188
+
189
+ def inpaint_on_gpu2(
190
+ seed,
191
+ process_width,
192
+ process_height,
193
+ prompt,
194
+ negative_prompt,
195
+ input_image,
196
+ mask_image,
197
+ num_inference_steps,
198
+ guidance_scale,
199
+ image_guidance_scale,
200
+ strength,
201
+ denoising_steps
202
+ ):
203
+ return input_image
204
+
205
+ @spaces.GPU(duration=420)
206
+ def inpaint_on_gpu(
207
+ seed,
208
+ process_width,
209
+ process_height,
210
+ prompt,
211
+ negative_prompt,
212
+ input_image,
213
+ mask_image,
214
+ num_inference_steps,
215
+ guidance_scale,
216
+ image_guidance_scale,
217
+ strength,
218
+ denoising_steps
219
+ ):
220
+ return pipe(
221
+ seeds = [seed],
222
+ width = process_width,
223
+ height = process_height,
224
+ prompt = prompt,
225
+ negative_prompt = negative_prompt,
226
+ image = input_image,
227
+ mask_image = mask_image,
228
+ num_inference_steps = num_inference_steps,
229
+ guidance_scale = guidance_scale,
230
+ image_guidance_scale = image_guidance_scale,
231
+ strength = strength,
232
+ denoising_steps = denoising_steps,
233
+ show_progress_bar = True
234
+ ).images[0]
235
+
236
+ with gr.Blocks() as interface:
237
+ gr.HTML(
238
+ """
239
+ <h1 style="text-align: center;">Inpaint</h1>
240
+ <p style="text-align: center;">Modifies one detail of your image, at any resolution, freely, without account, without watermark, without installation, which can be downloaded</p>
241
+ <br/>
242
+ <br/>
243
+ ✨ Powered by <i>SDXL 1.0</i> artificial intellingence. For illustration purpose, not information purpose. The new content is not based on real information but imagination.
244
+ <br/>
245
+ <ul>
246
+ <li>To change the <b>view angle</b> of your image, I recommend to use <i>Zero123</i>,</li>
247
+ <li>To <b>upscale</b> your image, I recommend to use <i><a href="https://huggingface.co/spaces/Fabrice-TIERCELIN/SUPIR">SUPIR</a></i>,</li>
248
+ <li>To <b>slightly change</b> your image, I recommend to use <i>Image-to-Image SDXL</i>,</li>
249
+ <li>If you need to enlarge the <b>viewpoint</b> of your image, I recommend you to use <i>Uncrop</i>,</li>
250
+ <li>To remove the <b>background</b> of your image, I recommend to use <i>BRIA</i>,</li>
251
+ <li>To make a <b>tile</b> of your image, I recommend to use <i>Make My Image Tile</i>,</li>
252
+ <li>To modify <b>anything else</b> on your image, I recommend to use <i>Instruct Pix2Pix</i>.</li>
253
+ </ul>
254
+ <br/>
255
+ """ + ("🏃‍♀️ Estimated time: few minutes. Current device: GPU." if torch.cuda.is_available() else "🐌 Slow process... ~1 hour. Current device: CPU.") + """
256
+ Your computer must not enter into standby mode.<br/>You can duplicate this space on a free account, it's designed to work on CPU, GPU and ZeroGPU.<br/>
257
+ <a href='https://huggingface.co/spaces/Fabrice-TIERCELIN/Inpaint?duplicate=true'><img src='https://img.shields.io/badge/-Duplicate%20Space-blue?labelColor=white&style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAP5JREFUOE+lk7FqAkEURY+ltunEgFXS2sZGIbXfEPdLlnxJyDdYB62sbbUKpLbVNhyYFzbrrA74YJlh9r079973psed0cvUD4A+4HoCjsA85X0Dfn/RBLBgBDxnQPfAEJgBY+A9gALA4tcbamSzS4xq4FOQAJgCDwV2CPKV8tZAJcAjMMkUe1vX+U+SMhfAJEHasQIWmXNN3abzDwHUrgcRGmYcgKe0bxrblHEB4E/pndMazNpSZGcsZdBlYJcEL9Afo75molJyM2FxmPgmgPqlWNLGfwZGG6UiyEvLzHYDmoPkDDiNm9JR9uboiONcBXrpY1qmgs21x1QwyZcpvxt9NS09PlsPAAAAAElFTkSuQmCC&logoWidth=14'></a>
258
+ <br/>
259
+ ⚖️ You can use, modify and share the generated images but not for commercial uses.
260
+
261
+ """
262
+ )
263
+ with gr.Column():
264
+ source_img = gr.ImageMask(label = "Your image", type = "pil", brush=gr.Brush(colors=["white"], color_mode="fixed"))
265
+ prompt = gr.Textbox(label = "Prompt", info = "Describe the subject, the background and the style of image; 77 token limit", placeholder = "Describe what you want to see in the entire image", lines = 2)
266
+ with gr.Accordion("Upload a mask", open = False):
267
+ uploaded_mask = gr.Image(label = "Already made mask (black pixels will be preserved, white pixels will be redrawn)", sources = ["upload"], type = "pil")
268
+ with gr.Accordion("Advanced options", open = False):
269
+ negative_prompt = gr.Textbox(label = "Negative prompt", placeholder = "Describe what you do NOT want to see in the entire image", value = "Ugly, malformed, noise, blur, watermark")
270
+ num_inference_steps = gr.Slider(minimum = 10, maximum = 100, value = 25, step = 1, label = "Number of inference steps", info = "lower=faster, higher=image quality")
271
+ guidance_scale = gr.Slider(minimum = 1, maximum = 13, value = 7, step = 0.1, label = "Classifier-Free Guidance Scale", info = "lower=image quality, higher=follow the prompt")
272
+ image_guidance_scale = gr.Slider(minimum = 1, value = 1.1, step = 0.1, label = "Image Guidance Scale", info = "lower=image quality, higher=follow the image")
273
+ strength = gr.Slider(value = 0.99, minimum = 0.01, maximum = 1.0, step = 0.01, label = "Strength", info = "lower=follow the original area, higher=redraw from scratch")
274
+ denoising_steps = gr.Number(minimum = 0, value = 1000, step = 1, label = "Denoising", info = "lower=irrelevant result, higher=relevant result")
275
+ randomize_seed = gr.Checkbox(label = "\U0001F3B2 Randomize seed", value = True, info = "If checked, result is always different")
276
+ seed = gr.Slider(minimum = 0, maximum = max_64_bit_int, step = 1, randomize = True, label = "Seed")
277
+ debug_mode = gr.Checkbox(label = "Debug mode", value = False, info = "Show intermediate results")
278
+
279
+ submit = gr.Button("🚀 Inpaint", variant = "primary")
280
+
281
+ inpainted_image = gr.Image(label = "Inpainted image")
282
+ information = gr.HTML()
283
+ original_image = gr.Image(label = "Original image", visible = False)
284
+ mask_image = gr.Image(label = "Mask image", visible = False)
285
+
286
+ submit.click(update_seed, inputs = [
287
+ randomize_seed, seed
288
+ ], outputs = [
289
+ seed
290
+ ], queue = False, show_progress = False).then(toggle_debug, debug_mode, [
291
+ original_image,
292
+ mask_image
293
+ ], queue = False, show_progress = False).then(check, inputs = [
294
+ source_img,
295
+ prompt,
296
+ uploaded_mask,
297
+ negative_prompt,
298
+ num_inference_steps,
299
+ guidance_scale,
300
+ image_guidance_scale,
301
+ strength,
302
+ denoising_steps,
303
+ randomize_seed,
304
+ seed,
305
+ debug_mode
306
+ ], outputs = [], queue = False, show_progress = False).success(inpaint, inputs = [
307
+ source_img,
308
+ prompt,
309
+ uploaded_mask,
310
+ negative_prompt,
311
+ num_inference_steps,
312
+ guidance_scale,
313
+ image_guidance_scale,
314
+ strength,
315
+ denoising_steps,
316
+ randomize_seed,
317
+ seed,
318
+ debug_mode
319
+ ], outputs = [
320
+ inpainted_image,
321
+ information,
322
+ original_image,
323
+ mask_image
324
+ ], scroll_to_output = True)
325
+
326
+ gr.Examples(
327
+ fn = inpaint,
328
+ inputs = [
329
+ source_img,
330
+ prompt,
331
+ uploaded_mask,
332
+ negative_prompt,
333
+ num_inference_steps,
334
+ guidance_scale,
335
+ image_guidance_scale,
336
+ strength,
337
+ denoising_steps,
338
+ randomize_seed,
339
+ seed,
340
+ debug_mode
341
+ ],
342
+ outputs = [
343
+ inpainted_image,
344
+ information,
345
+ original_image,
346
+ mask_image
347
+ ],
348
+ examples = [
349
+ [
350
+ "./Examples/Example1.png",
351
+ "A deer, in a forest landscape, ultrarealistic, realistic, photorealistic, 8k",
352
+ "./Examples/Mask1.webp",
353
+ "Ugly, malformed, painting, drawing, cartoon, anime, 3d, noise, blur, watermark",
354
+ 25,
355
+ 7,
356
+ 1.1,
357
+ 0.99,
358
+ 1000,
359
+ False,
360
+ 42,
361
+ False
362
+ ],
363
+ [
364
+ "./Examples/Example3.jpg",
365
+ "An angry old woman, ultrarealistic, realistic, photorealistic, 8k",
366
+ "./Examples/Mask3.gif",
367
+ "Ugly, malformed, painting, drawing, cartoon, anime, 3d, noise, blur, watermark",
368
+ 25,
369
+ 7,
370
+ 1.5,
371
+ 0.99,
372
+ 1000,
373
+ False,
374
+ 42,
375
+ False
376
+ ],
377
+ [
378
+ "./Examples/Example4.gif",
379
+ "A laptop, ultrarealistic, realistic, photorealistic, 8k",
380
+ "./Examples/Mask4.bmp",
381
+ "Ugly, malformed, painting, drawing, cartoon, anime, 3d, noise, blur, watermark",
382
+ 25,
383
+ 7,
384
+ 1.1,
385
+ 0.99,
386
+ 1000,
387
+ False,
388
+ 42,
389
+ False
390
+ ],
391
+ [
392
+ "./Examples/Example5.bmp",
393
+ "A sand castle, ultrarealistic, realistic, photorealistic, 8k",
394
+ "./Examples/Mask5.png",
395
+ "Ugly, malformed, painting, drawing, cartoon, anime, 3d, noise, blur, watermark",
396
+ 50,
397
+ 7,
398
+ 1.5,
399
+ 0.5,
400
+ 1000,
401
+ False,
402
+ 42,
403
+ False
404
+ ],
405
+ [
406
+ "./Examples/Example2.webp",
407
+ "A cat, ultrarealistic, realistic, photorealistic, 8k",
408
+ "./Examples/Mask2.png",
409
+ "Ugly, malformed, painting, drawing, cartoon, anime, 3d, noise, blur, watermark",
410
+ 25,
411
+ 7,
412
+ 1.1,
413
+ 0.99,
414
+ 1000,
415
+ False,
416
+ 42,
417
+ False
418
+ ],
419
+ ],
420
+ cache_examples = False,
421
+ )
422
+
423
+ gr.Markdown(
424
+ """
425
+ ## How to prompt your image
426
+
427
+ To easily read your prompt, start with the subject, then describ the pose or action, then secondary elements, then the background, then the graphical style, then the image quality:
428
+ ```
429
+ A Vietnamese woman, red clothes, walking, smilling, in the street, a car on the left, in a modern city, photorealistic, 8k
430
+ ```
431
+
432
+ You can use round brackets to increase the importance of a part:
433
+ ```
434
+ A Vietnamese woman, (red clothes), walking, smilling, in the street, a car on the left, in a modern city, photorealistic, 8k
435
+ ```
436
+
437
+ You can use several levels of round brackets to even more increase the importance of a part:
438
+ ```
439
+ A Vietnamese woman, ((red clothes)), (walking), smilling, in the street, a car on the left, in a modern city, photorealistic, 8k
440
+ ```
441
+
442
+ You can use number instead of several round brackets:
443
+ ```
444
+ A Vietnamese woman, (red clothes:1.5), (walking), smilling, in the street, a car on the left, in a modern city, photorealistic, 8k
445
+ ```
446
+
447
+ You can do the same thing with square brackets to decrease the importance of a part:
448
+ ```
449
+ A [Vietnamese] woman, (red clothes:1.5), (walking), smilling, in the street, a car on the left, in a modern city, photorealistic, 8k
450
+ ```
451
+
452
+ To easily read your negative prompt, organize it the same way as your prompt (not important for the AI):
453
+ ```
454
+ man, boy, hat, running, tree, bicycle, forest, drawing, painting, cartoon, 3d, monochrome, blurry, noisy, bokeh
455
+ ```
456
+ """
457
+ )
458
+
459
  interface.queue().launch()