openfree commited on
Commit
dd58cc1
·
verified ·
1 Parent(s): cfbaa8a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +305 -99
app.py CHANGED
@@ -1,15 +1,11 @@
1
  import gradio as gr
2
  import numpy as np
3
-
4
- import spaces
5
  import torch
6
  import spaces
7
  import random
8
-
9
  from diffusers import AutoPipelineForText2Image
10
  from PIL import Image
11
 
12
-
13
  MAX_SEED = np.iinfo(np.int32).max
14
  MAX_IMAGE_SIZE = 2048
15
 
@@ -19,47 +15,9 @@ pipe = AutoPipelineForText2Image.from_pretrained(
19
  torch_dtype=torch.bfloat16,
20
  ).to("cuda")
21
 
22
- # def calculate_optimal_dimensions(image: Image.Image):
23
- # # Extract the original dimensions
24
- # original_width, original_height = image.size
25
-
26
- # # Set constants
27
- # MIN_ASPECT_RATIO = 9 / 16
28
- # MAX_ASPECT_RATIO = 16 / 9
29
- # FIXED_DIMENSION = 1024
30
-
31
- # # Calculate the aspect ratio of the original image
32
- # original_aspect_ratio = original_width / original_height
33
-
34
- # # Determine which dimension to fix
35
- # if original_aspect_ratio > 1: # Wider than tall
36
- # width = FIXED_DIMENSION
37
- # height = round(FIXED_DIMENSION / original_aspect_ratio)
38
- # else: # Taller than wide
39
- # height = FIXED_DIMENSION
40
- # width = round(FIXED_DIMENSION * original_aspect_ratio)
41
-
42
- # # Ensure dimensions are multiples of 8
43
- # width = (width // 8) * 8
44
- # height = (height // 8) * 8
45
-
46
- # # Enforce aspect ratio limits
47
- # calculated_aspect_ratio = width / height
48
- # if calculated_aspect_ratio > MAX_ASPECT_RATIO:
49
- # width = (height * MAX_ASPECT_RATIO // 8) * 8
50
- # elif calculated_aspect_ratio < MIN_ASPECT_RATIO:
51
- # height = (width / MIN_ASPECT_RATIO // 8) * 8
52
-
53
- # # Ensure width and height remain above the minimum dimensions
54
- # width = max(width, 576) if width == FIXED_DIMENSION else width
55
- # height = max(height, 576) if height == FIXED_DIMENSION else height
56
-
57
- # return width, height
58
-
59
  @spaces.GPU
60
- 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)):
61
  image = edit_images["background"].convert("RGB")
62
- # width, height = calculate_optimal_dimensions(image)
63
  mask = edit_images["layers"][0].convert("RGB")
64
  if randomize_seed:
65
  seed = random.randint(0, MAX_SEED)
@@ -76,80 +34,328 @@ def infer(edit_images, prompt, seed=42, randomize_seed=False, width=1024, height
76
  generator=torch.Generator("cpu").manual_seed(seed)
77
  ).images[0]
78
  return (image, out_image), seed
79
-
 
 
 
 
 
 
 
80
  examples = [
81
  "a tiny astronaut hatching from an egg on the moon",
82
  "a cat holding a sign that says hello world",
83
  "an anime illustration of a wiener schnitzel",
84
  ]
85
 
86
- css="""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  #col-container {
88
  margin: 0 auto;
89
- max-width: 1000px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  }
91
  """
92
 
93
- with gr.Blocks(css=css) as demo:
94
-
95
  with gr.Column(elem_id="col-container"):
96
- gr.Markdown(f"""# Flex.2 Preview - Inpaint
97
- Inpainting demo for Flex.2 Preview - Open Source 8B parameter Text to Image Diffusion Model with universal control and built-in inpainting support
98
- trained and devloped by [ostris](https://huggingface.co/ostris)
99
- [[apache-2.0 license](https://huggingface.co/datasets/choosealicense/licenses/blob/main/markdown/apache-2.0.md)] [[model](https://huggingface.co/ostris/Flex.2-preview)]
100
- """)
101
- with gr.Row():
102
- with gr.Column():
103
- edit_image = gr.ImageEditor(
104
- label='Upload and draw mask for inpainting',
105
- type='pil',
106
- sources=["upload", "webcam"],
107
- image_mode='RGB',
108
- layers=False,
109
- brush=gr.Brush(colors=["#FFFFFF"], color_mode="fixed"),
110
- height=600
111
- )
112
- prompt = gr.Text(
113
- label="Prompt",
114
- show_label=False,
115
- max_lines=1,
116
- placeholder="Enter your prompt",
117
- container=False,
118
- )
119
- run_button = gr.Button("Run")
120
-
121
- result = gr.ImageSlider(label="Generated Image", type="pil", image_mode='RGB')
122
 
123
- with gr.Accordion("Advanced Settings", open=False):
124
-
125
- seed = gr.Slider(
126
- label="Seed",
127
- minimum=0,
128
- maximum=MAX_SEED,
129
- step=1,
130
- value=0,
131
- )
132
-
133
- randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
134
-
135
  with gr.Row():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
 
137
- height = gr.Slider(64, 2048, value=512, step=64, label="Height")
138
- width = gr.Slider(64, 2048, value=512, step=64, label="Width")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
- with gr.Row():
141
-
142
- guidance_scale = gr.Slider(0.0, 20.0, value=3.5, step=0.1, label="Guidance Scale")
143
- control_strength = gr.Slider(0.0, 1.0, value=0.5, step=0.05, label="Control Strength")
144
- control_stop = gr.Slider(0.0, 1.0, value=0.33, step=0.05, label="Control Stop")
145
- num_inference_steps = gr.Slider(1, 100, value=50, step=1, label="Inference Steps")
 
 
 
 
 
 
 
 
 
 
146
 
 
147
  run_button.click(
148
- fn = infer,
149
- inputs = [edit_image, prompt, seed, randomize_seed, width, height, guidance_scale, control_strength, control_stop, num_inference_steps],
150
- outputs = [result, seed]
151
  )
152
 
153
-
154
-
155
  demo.launch()
 
1
  import gradio as gr
2
  import numpy as np
 
 
3
  import torch
4
  import spaces
5
  import random
 
6
  from diffusers import AutoPipelineForText2Image
7
  from PIL import Image
8
 
 
9
  MAX_SEED = np.iinfo(np.int32).max
10
  MAX_IMAGE_SIZE = 2048
11
 
 
15
  torch_dtype=torch.bfloat16,
16
  ).to("cuda")
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  @spaces.GPU
19
+ 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)):
20
  image = edit_images["background"].convert("RGB")
 
21
  mask = edit_images["layers"][0].convert("RGB")
22
  if randomize_seed:
23
  seed = random.randint(0, MAX_SEED)
 
34
  generator=torch.Generator("cpu").manual_seed(seed)
35
  ).images[0]
36
  return (image, out_image), seed
37
+
38
+ def create_example_card(example):
39
+ return f"""
40
+ <div class="example-card">
41
+ <p>{example}</p>
42
+ </div>
43
+ """
44
+
45
  examples = [
46
  "a tiny astronaut hatching from an egg on the moon",
47
  "a cat holding a sign that says hello world",
48
  "an anime illustration of a wiener schnitzel",
49
  ]
50
 
51
+ example_html = "".join([create_example_card(ex) for ex in examples])
52
+
53
+ css = """
54
+ :root {
55
+ --primary-color: #7E57C2;
56
+ --secondary-color: #5E35B1;
57
+ --accent-color: #B39DDB;
58
+ --background-color: #F5F5F7;
59
+ --card-background: #FFFFFF;
60
+ --text-color: #333333;
61
+ --shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
62
+ --radius: 12px;
63
+ }
64
+
65
+ body {
66
+ font-family: 'Inter', system-ui, sans-serif;
67
+ background-color: var(--background-color);
68
+ }
69
+
70
  #col-container {
71
  margin: 0 auto;
72
+ max-width: 1200px;
73
+ padding: 0;
74
+ }
75
+
76
+ .container {
77
+ background-color: var(--card-background);
78
+ border-radius: var(--radius);
79
+ box-shadow: var(--shadow);
80
+ padding: 24px;
81
+ margin-bottom: 24px;
82
+ }
83
+
84
+ .header-container {
85
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
86
+ border-radius: var(--radius);
87
+ padding: 32px;
88
+ margin-bottom: 24px;
89
+ color: white;
90
+ text-align: center;
91
+ box-shadow: var(--shadow);
92
+ }
93
+
94
+ .header-container h1 {
95
+ font-weight: 700;
96
+ font-size: 2.5rem;
97
+ margin-bottom: 8px;
98
+ background: linear-gradient(to right, #ffffff, #e0e0e0);
99
+ -webkit-background-clip: text;
100
+ background-clip: text;
101
+ -webkit-text-fill-color: transparent;
102
+ }
103
+
104
+ .header-container p {
105
+ font-size: 1.1rem;
106
+ opacity: 0.92;
107
+ margin-bottom: 16px;
108
+ }
109
+
110
+ .header-container a {
111
+ color: var(--accent-color);
112
+ text-decoration: underline;
113
+ transition: opacity 0.2s;
114
+ }
115
+
116
+ .header-container a:hover {
117
+ opacity: 0.8;
118
+ }
119
+
120
+ .btn-primary {
121
+ background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
122
+ border: none;
123
+ border-radius: 8px;
124
+ color: white;
125
+ font-weight: 600;
126
+ padding: 12px 24px;
127
+ font-size: 16px;
128
+ cursor: pointer;
129
+ transition: all 0.3s ease;
130
+ box-shadow: 0 4px 12px rgba(126, 87, 194, 0.3);
131
+ }
132
+
133
+ .btn-primary:hover {
134
+ transform: translateY(-2px);
135
+ box-shadow: 0 6px 16px rgba(126, 87, 194, 0.4);
136
+ }
137
+
138
+ .image-editor-container {
139
+ border-radius: var(--radius);
140
+ overflow: hidden;
141
+ box-shadow: var(--shadow);
142
+ }
143
+
144
+ .prompt-container {
145
+ background-color: var(--card-background);
146
+ border-radius: var(--radius);
147
+ padding: 16px;
148
+ box-shadow: var(--shadow);
149
+ margin-top: 16px;
150
+ }
151
+
152
+ .result-container {
153
+ border-radius: var(--radius);
154
+ overflow: hidden;
155
+ box-shadow: var(--shadow);
156
+ }
157
+
158
+ .settings-container {
159
+ background-color: var(--card-background);
160
+ border-radius: var(--radius);
161
+ padding: 20px;
162
+ box-shadow: var(--shadow);
163
+ margin-top: 16px;
164
+ }
165
+
166
+ .example-section {
167
+ background-color: var(--card-background);
168
+ border-radius: var(--radius);
169
+ padding: 20px;
170
+ box-shadow: var(--shadow);
171
+ margin-top: 24px;
172
+ }
173
+
174
+ .example-section h3 {
175
+ font-size: 1.3rem;
176
+ font-weight: 600;
177
+ margin-bottom: 16px;
178
+ color: var(--primary-color);
179
+ }
180
+
181
+ .examples-grid {
182
+ display: flex;
183
+ flex-wrap: wrap;
184
+ gap: 12px;
185
+ }
186
+
187
+ .example-card {
188
+ background: linear-gradient(135deg, #f3f3f7, #ffffff);
189
+ border-radius: 8px;
190
+ padding: 16px;
191
+ cursor: pointer;
192
+ transition: all 0.2s ease;
193
+ border: 1px solid #e0e0e0;
194
+ flex: 1;
195
+ min-width: 200px;
196
+ }
197
+
198
+ .example-card:hover {
199
+ transform: translateY(-2px);
200
+ box-shadow: var(--shadow);
201
+ border-color: var(--accent-color);
202
+ }
203
+
204
+ .example-card p {
205
+ margin: 0;
206
+ font-size: 14px;
207
+ color: var(--text-color);
208
+ }
209
+
210
+ .accordion-header {
211
+ font-weight: 600;
212
+ color: var(--primary-color);
213
+ }
214
+
215
+ /* Custom slider styling */
216
+ input[type="range"] {
217
+ height: 6px;
218
+ border-radius: 3px;
219
+ background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
220
+ }
221
+
222
+ input[type="range"]::-webkit-slider-thumb {
223
+ background: var(--primary-color);
224
+ border: 2px solid white;
225
+ height: 18px;
226
+ width: 18px;
227
+ }
228
+
229
+ .footer {
230
+ text-align: center;
231
+ padding: 24px;
232
+ color: #777;
233
+ font-size: 14px;
234
+ }
235
+
236
+ /* Animate the result transition */
237
+ @keyframes fadeIn {
238
+ from { opacity: 0; }
239
+ to { opacity: 1; }
240
+ }
241
+
242
+ .result-animation {
243
+ animation: fadeIn 0.5s ease-in-out;
244
+ }
245
+
246
+ /* Responsive adjustments */
247
+ @media (max-width: 768px) {
248
+ .examples-grid {
249
+ flex-direction: column;
250
+ }
251
  }
252
  """
253
 
254
+ with gr.Blocks(css=css, theme=gr.themes.Monochrome()) as demo:
 
255
  with gr.Column(elem_id="col-container"):
256
+ # Header with gradient
257
+ with gr.Column(elem_classes=["header-container"]):
258
+ gr.HTML("""
259
+ <h1>Flex.2 Preview - Inpaint</h1>
260
+ <p>Advanced 8B parameter Text to Image Diffusion Model with universal control and built-in inpainting support</p>
261
+ <p>Created by <a href="https://huggingface.co/ostris" target="_blank">ostris</a> |
262
+ <a href="https://huggingface.co/datasets/choosealicense/licenses/blob/main/markdown/apache-2.0.md" target="_blank">apache-2.0 license</a> |
263
+ <a href="https://huggingface.co/ostris/Flex.2-preview" target="_blank">model</a></p>
264
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
 
266
+ # Main interface container
267
+ with gr.Column(elem_classes=["container"]):
 
 
 
 
 
 
 
 
 
 
268
  with gr.Row():
269
+ # Left column: Input
270
+ with gr.Column(scale=1):
271
+ with gr.Column(elem_classes=["image-editor-container"]):
272
+ edit_image = gr.ImageEditor(
273
+ label='Upload and draw mask for inpainting',
274
+ type='pil',
275
+ sources=["upload", "webcam"],
276
+ image_mode='RGB',
277
+ layers=False,
278
+ brush=gr.Brush(colors=["#FFFFFF"], color_mode="fixed"),
279
+ height=500
280
+ )
281
+
282
+ with gr.Column(elem_classes=["prompt-container"]):
283
+ prompt = gr.Text(
284
+ label="Your creative prompt",
285
+ show_label=True,
286
+ max_lines=1,
287
+ placeholder="Describe what you want to generate...",
288
+ container=True,
289
+ )
290
+
291
+ run_button = gr.Button("✨ Generate", elem_classes=["btn-primary"])
292
 
293
+ # Right column: Output
294
+ with gr.Column(scale=1, elem_classes=["result-container"]):
295
+ result = gr.ImageSlider(
296
+ label="Before & After",
297
+ type="pil",
298
+ image_mode='RGB',
299
+ elem_classes=["result-animation"]
300
+ )
301
+
302
+ # Advanced settings in a nice container
303
+ with gr.Column(elem_classes=["settings-container"]):
304
+ with gr.Accordion("Advanced Settings", open=False, elem_classes=["accordion-header"]):
305
+ with gr.Column():
306
+ with gr.Row():
307
+ seed = gr.Slider(
308
+ label="Seed",
309
+ minimum=0,
310
+ maximum=MAX_SEED,
311
+ step=1,
312
+ value=0,
313
+ )
314
+ randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
315
+
316
+ with gr.Row():
317
+ height = gr.Slider(64, 2048, value=512, step=64, label="Height")
318
+ width = gr.Slider(64, 2048, value=512, step=64, label="Width")
319
+
320
+ with gr.Row():
321
+ guidance_scale = gr.Slider(0.0, 20.0, value=3.5, step=0.1, label="Guidance Scale")
322
+ control_strength = gr.Slider(0.0, 1.0, value=0.5, step=0.05, label="Control Strength")
323
+
324
+ with gr.Row():
325
+ control_stop = gr.Slider(0.0, 1.0, value=0.33, step=0.05, label="Control Stop")
326
+ num_inference_steps = gr.Slider(1, 100, value=50, step=1, label="Inference Steps")
327
+
328
+ # Example prompts section
329
+ with gr.Column(elem_classes=["example-section"]):
330
+ gr.HTML(f"""
331
+ <h3>Try these example prompts:</h3>
332
+ <div class="examples-grid">
333
+ {example_html}
334
+ </div>
335
+ """)
336
 
337
+ # Example functionality
338
+ for i, example in enumerate(examples):
339
+ gr.HTML(f"""
340
+ <script>
341
+ document.querySelectorAll('.example-card')[{i}].addEventListener('click', function() {{
342
+ document.querySelector('textarea').value = "{example}";
343
+ }});
344
+ </script>
345
+ """)
346
+
347
+ # Footer
348
+ gr.HTML("""
349
+ <div class="footer">
350
+ <p>Powered by Gradio • Flex.2 Preview Inpainting Demo</p>
351
+ </div>
352
+ """)
353
 
354
+ # Handle examples click to populate prompt
355
  run_button.click(
356
+ fn=infer,
357
+ inputs=[edit_image, prompt, seed, randomize_seed, width, height, guidance_scale, control_strength, control_stop, num_inference_steps],
358
+ outputs=[result, seed]
359
  )
360
 
 
 
361
  demo.launch()