1
+ import gradio as gr
2
+ import numpy as np
3
+ import torch
4
+ import random
5
+ from PIL import Image , ImageFilter
6
+
7
+ MAX_SEED = np .iinfo (np .int32 ).max
8
+ MAX_IMAGE_SIZE = 2048
9
+
10
+
11
+ def make_demo (pipe ):
12
+ def infer (edit_images , prompt , seed = 42 , randomize_seed = False , width = 1024 , height = 1024 , guidance_scale = 3.5 , control_strength = 0.5 , control_stop = 0.33 , num_inference_steps = 50 , progress = gr .Progress (track_tqdm = True )):
13
+ image = edit_images ["background" ].convert ("RGB" )
14
+ mask = Image .fromarray (np .array (edit_images ["layers" ][- 1 ])[:, :, - 1 ])
15
+ if randomize_seed :
16
+ seed = random .randint (0 , MAX_SEED )
17
+ out_image = pipe (
18
+ prompt = prompt ,
19
+ inpaint_image = image ,
20
+ inpaint_mask = mask ,
21
+ height = height ,
22
+ width = width ,
23
+ guidance_scale = guidance_scale ,
24
+ control_strength = control_strength ,
25
+ control_stop = control_stop ,
26
+ num_inference_steps = num_inference_steps ,
27
+ generator = torch .Generator ("cpu" ).manual_seed (seed )
28
+ ).images [0 ]
29
+ return (image , out_image ), seed
30
+
31
+ css = """
32
+ :root {
33
+ --primary-color: #7E57C2;
34
+ --secondary-color: #5E35B1;
35
+ --accent-color: #B39DDB;
36
+ --background-color: #F5F5F7;
37
+ --card-background: #FFFFFF;
38
+ --text-color: #333333;
39
+ --shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
40
+ --radius: 12px;
41
+ }
42
+ body {
43
+ font-family: 'Inter', system-ui, sans-serif;
44
+ background-color: var(--background-color);
45
+ }
46
+ #col-container {
47
+ margin: 0 auto;
48
+ max-width: 1200px;
49
+ padding: 0;
50
+ }
51
+ .container {
52
+ background-color: var(--card-background);
53
+ border-radius: var(--radius);
54
+ box-shadow: var(--shadow);
55
+ padding: 24px;
56
+ margin-bottom: 24px;
57
+ }
58
+ .header-container {
59
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
60
+ border-radius: var(--radius);
61
+ padding: 32px;
62
+ margin-bottom: 24px;
63
+ color: white;
64
+ text-align: center;
65
+ box-shadow: var(--shadow);
66
+ }
67
+ .header-container h1 {
68
+ font-weight: 700;
69
+ font-size: 2.5rem;
70
+ margin-bottom: 8px;
71
+ background: linear-gradient(to right, #ffffff, #e0e0e0);
72
+ -webkit-background-clip: text;
73
+ background-clip: text;
74
+ -webkit-text-fill-color: transparent;
75
+ }
76
+ .header-container p {
77
+ font-size: 1.1rem;
78
+ opacity: 0.92;
79
+ margin-bottom: 16px;
80
+ }
81
+ .header-container a {
82
+ color: var(--accent-color);
83
+ text-decoration: underline;
84
+ transition: opacity 0.2s;
85
+ }
86
+ .header-container a:hover {
87
+ opacity: 0.8;
88
+ }
89
+ .btn-primary {
90
+ background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
91
+ border: none;
92
+ border-radius: 8px;
93
+ color: white;
94
+ font-weight: 600;
95
+ padding: 12px 24px;
96
+ font-size: 16px;
97
+ cursor: pointer;
98
+ transition: all 0.3s ease;
99
+ box-shadow: 0 4px 12px rgba(126, 87, 194, 0.3);
100
+ }
101
+ .btn-primary:hover {
102
+ transform: translateY(-2px);
103
+ box-shadow: 0 6px 16px rgba(126, 87, 194, 0.4);
104
+ }
105
+ .image-editor-container {
106
+ border-radius: var(--radius);
107
+ overflow: hidden;
108
+ box-shadow: var(--shadow);
109
+ }
110
+ .prompt-container {
111
+ background-color: var(--card-background);
112
+ border-radius: var(--radius);
113
+ padding: 16px;
114
+ box-shadow: var(--shadow);
115
+ margin-top: 16px;
116
+ }
117
+ .result-container {
118
+ border-radius: var(--radius);
119
+ overflow: hidden;
120
+ box-shadow: var(--shadow);
121
+ }
122
+ .settings-container {
123
+ background-color: var(--card-background);
124
+ border-radius: var(--radius);
125
+ padding: 20px;
126
+ box-shadow: var(--shadow);
127
+ margin-top: 16px;
128
+ }
129
+ .accordion-header {
130
+ font-weight: 600;
131
+ color: var(--primary-color);
132
+ }
133
+ /* Custom slider styling */
134
+ input[type="range"] {
135
+ height: 6px;
136
+ border-radius: 3px;
137
+ background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
138
+ }
139
+ input[type="range"]::-webkit-slider-thumb {
140
+ background: var(--primary-color);
141
+ border: 2px solid white;
142
+ height: 18px;
143
+ width: 18px;
144
+ }
145
+ .footer {
146
+ text-align: center;
147
+ padding: 24px;
148
+ color: #777;
149
+ font-size: 14px;
150
+ }
151
+ /* Animate the result transition */
152
+ @keyframes fadeIn {
153
+ from { opacity: 0; }
154
+ to { opacity: 1; }
155
+ }
156
+ .result-animation {
157
+ animation: fadeIn 0.5s ease-in-out;
158
+ }
159
+ """
160
+
161
+ with gr .Blocks (css = css , theme = gr .themes .Monochrome ()) as demo :
162
+ with gr .Column (elem_id = "col-container" ):
163
+ # Header with gradient
164
+ with gr .Column (elem_classes = ["header-container" ]):
165
+ gr .HTML ("""
166
+ <h1>Flex.2 Preview Inpainting OpenVINO Demo</h1>
167
+ """ )
168
+ # Main interface container
169
+ with gr .Column (elem_classes = ["container" ]):
170
+ with gr .Row ():
171
+ # Left column: Input
172
+ with gr .Column (scale = 1 ):
173
+ edit_image = gr .ImageEditor (
174
+ label = 'Upload and draw mask for inpainting' ,
175
+ type = 'pil' ,
176
+ sources = ["upload" , "webcam" ],
177
+ image_mode = 'RGB' ,
178
+ layers = False ,
179
+ brush = gr .Brush (colors = ["#FFFFFF" ], color_mode = "fixed" ),
180
+ height = 500
181
+ )
182
+
183
+ with gr .Column (elem_classes = ["prompt-container" ]):
184
+ prompt = gr .Text (
185
+ label = "Your creative prompt" ,
186
+ show_label = True ,
187
+ max_lines = 1 ,
188
+ placeholder = "Describe what you want to generate..." ,
189
+ container = True ,
190
+ )
191
+
192
+ run_button = gr .Button ("✨ Generate" , elem_classes = ["btn-primary" ])
193
+ # Right column: Output
194
+ with gr .Column (scale = 1 , elem_classes = ["result-container" ]):
195
+ result = gr .ImageSlider (
196
+ label = "Before & After" ,
197
+ type = "pil" ,
198
+ image_mode = 'RGB' ,
199
+ elem_classes = ["result-animation" ]
200
+ )
201
+
202
+ # Advanced settings in a nice container
203
+ with gr .Column (elem_classes = ["settings-container" ]):
204
+ with gr .Accordion ("Advanced Settings" , open = False , elem_classes = ["accordion-header" ]):
205
+ with gr .Column ():
206
+ with gr .Row ():
207
+ seed = gr .Slider (
208
+ label = "Seed" ,
209
+ minimum = 0 ,
210
+ maximum = MAX_SEED ,
211
+ step = 1 ,
212
+ value = 0 ,
213
+ )
214
+ randomize_seed = gr .Checkbox (label = "Randomize seed" , value = True )
215
+
216
+ with gr .Row ():
217
+ height = gr .Slider (64 , 2048 , value = 512 , step = 64 , label = "Height" )
218
+ width = gr .Slider (64 , 2048 , value = 512 , step = 64 , label = "Width" )
219
+
220
+ with gr .Row ():
221
+ guidance_scale = gr .Slider (0.0 , 20.0 , value = 3.5 , step = 0.1 , label = "Guidance Scale" )
222
+ control_strength = gr .Slider (0.0 , 1.0 , value = 0.5 , step = 0.05 , label = "Control Strength" )
223
+
224
+ with gr .Row ():
225
+ control_stop = gr .Slider (0.0 , 1.0 , value = 0.33 , step = 0.05 , label = "Control Stop" )
226
+ num_inference_steps = gr .Slider (1 , 100 , value = 20 , step = 1 , label = "Inference Steps" )
227
+
228
+ # Footer
229
+ gr .HTML ("""
230
+ <div class="footer">
231
+ <p>Flex.2 Preview Inpainting OpenVINO Demo</p>
232
+ </div>
233
+ """ )
234
+
235
+ run_button .click (
236
+ fn = infer ,
237
+ inputs = [edit_image , prompt , seed , randomize_seed , width , height , guidance_scale , control_strength , control_stop , num_inference_steps ],
238
+ outputs = [result , seed ]
239
+ )
240
+
241
+ return demo
0 commit comments