drdudddd commited on
Commit
b5cdf56
·
verified ·
1 Parent(s): 0e857eb

Upload app(5).py

Browse files
Files changed (1) hide show
  1. app(5).py +519 -0
app(5).py ADDED
@@ -0,0 +1,519 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from gradio_client import Client, handle_file
3
+ import re
4
+ import torch
5
+ from diffusers import FluxPipeline
6
+ import os
7
+
8
+ # Instantiate a Client object from gradio_client pointing to the 'selfit-camera/Omni-Image-Editor' Space.
9
+ client = Client("selfit-camera/Omni-Image-Editor")
10
+
11
+ # Instantiate a Client object for video generation using alexnasa/ltx-2-TURBO Space.
12
+ video_client = Client("alexnasa/ltx-2-TURBO")
13
+
14
+ # Initialize the Flux pipeline for GPU-accelerated image generation
15
+ pipe = None
16
+
17
+ def initialize_pipe():
18
+ """Initialize the Flux pipeline for image generation."""
19
+ global pipe
20
+ if pipe is None:
21
+ try:
22
+ print("Loading Flux pipeline...")
23
+ pipe = FluxPipeline.from_pretrained(
24
+ "black-forest-labs/FLUX.1-dev",
25
+ torch_dtype=torch.bfloat16
26
+ )
27
+ pipe.enable_attention_slicing()
28
+ pipe = pipe.to("cuda")
29
+ print("Flux pipeline loaded successfully!")
30
+ except Exception as e:
31
+ print(f"Error loading Flux pipeline: {str(e)}")
32
+ raise gr.Error(f"Failed to load image generation model: {str(e)}")
33
+
34
+ # Define a Python function for local GPU-accelerated image generation
35
+ def generate_image_gpu(prompt, height, width, num_inference_steps, seed, randomize_seed, num_images):
36
+ """
37
+ Generate images locally using Flux model on GPU.
38
+
39
+ Args:
40
+ prompt (str): Text description of the image to generate
41
+ height (int): Height of the image in pixels
42
+ width (int): Width of the image in pixels
43
+ num_inference_steps (int): Number of inference steps
44
+ seed (int): Random seed for reproducibility
45
+ randomize_seed (bool): Whether to randomize the seed
46
+ num_images (int): Number of images to generate (1-4)
47
+
48
+ Returns:
49
+ tuple: (list of generated PIL images, seed used)
50
+ """
51
+ try:
52
+ # Initialize pipeline if not already done
53
+ initialize_pipe()
54
+
55
+ # Validate prompt
56
+ if not prompt or not prompt.strip():
57
+ raise gr.Error("Please enter a prompt.")
58
+
59
+ # Randomize seed if requested
60
+ if randomize_seed:
61
+ seed = torch.randint(0, 2**32 - 1, (1,)).item()
62
+
63
+ # Clamp number of images to valid range (1-4)
64
+ num_images = min(max(1, int(num_images)), 4)
65
+
66
+ # Create generator with seed
67
+ generator = torch.Generator("cuda").manual_seed(int(seed))
68
+
69
+ # Generate images
70
+ with torch.no_grad():
71
+ result = pipe(
72
+ prompt=prompt,
73
+ height=int(height),
74
+ width=int(width),
75
+ num_inference_steps=int(num_inference_steps),
76
+ guidance_scale=0.0,
77
+ generator=generator,
78
+ max_sequence_length=1024,
79
+ num_images_per_prompt=num_images,
80
+ output_type="pil",
81
+ )
82
+
83
+ return result.images, seed
84
+
85
+ except gr.Error:
86
+ raise
87
+ except Exception as e:
88
+ raise gr.Error(f"Error generating images: {str(e)}")
89
+
90
+ # Define a Python function for text-to-image generation
91
+ def generate_image(prompt):
92
+ """
93
+ Generate an image from a text prompt using the Omni Image Editor API.
94
+
95
+ Args:
96
+ prompt (str): Text description of the image to generate
97
+
98
+ Returns:
99
+ str: URL of the generated image or error message
100
+ """
101
+ try:
102
+ # Call the client.predict() method with the user's prompt, aspect_ratio='16:9', and api_name='/text_to_image_interface'.
103
+ result = client.predict(
104
+ prompt=prompt,
105
+ aspect_ratio="16:9",
106
+ api_name="/text_to_image_interface"
107
+ )
108
+
109
+ # The predict method returns a tuple. The first element of this tuple is an HTML string containing the image.
110
+ # Extract the image URL from this HTML string.
111
+ html_string = result[0]
112
+ match = re.search(r"src='([^']+)'", html_string)
113
+ if match:
114
+ image_url = match.group(1)
115
+ return image_url
116
+ else:
117
+ # Handle cases where the URL might not be found
118
+ return "https://via.placeholder.com/400x200?text=Error:Image+Not+Found"
119
+ except Exception as e:
120
+ return f"Error generating image: {str(e)}"
121
+
122
+ # Define a Python function for image editing
123
+ def edit_image(input_image, edit_prompt):
124
+ """
125
+ Edit an image based on a text prompt using the Omni Image Editor API.
126
+
127
+ Args:
128
+ input_image (str): Path to the image file or image object
129
+ edit_prompt (str): Text description of the edits to apply
130
+
131
+ Returns:
132
+ str: URL of the edited image or error message
133
+ """
134
+ try:
135
+ if input_image is None:
136
+ return "Please upload an image first"
137
+
138
+ # Use handle_file to properly handle the image upload
139
+ result = client.predict(
140
+ input_image=handle_file(input_image),
141
+ prompt=edit_prompt,
142
+ api_name="/edit_image_interface"
143
+ )
144
+
145
+ # Extract the image URL from the HTML response
146
+ if isinstance(result, tuple) and len(result) > 0:
147
+ html_string = result[0]
148
+ match = re.search(r"src='([^']+)'", html_string)
149
+ if match:
150
+ image_url = match.group(1)
151
+ return image_url
152
+ else:
153
+ return "https://via.placeholder.com/400x200?text=Error:Image+Not+Found"
154
+ else:
155
+ return str(result)
156
+
157
+ except Exception as e:
158
+ return f"Error editing image: {str(e)}"
159
+
160
+ # Define a Python function for image upscaling
161
+ def upscale_image(input_image):
162
+ """
163
+ Upscale an image to higher resolution using the Omni Image Editor API.
164
+
165
+ Args:
166
+ input_image (str): Path to the image file or image object to upscale
167
+
168
+ Returns:
169
+ str: URL of the upscaled image or error message
170
+ """
171
+ try:
172
+ if input_image is None:
173
+ return "Please upload an image first"
174
+
175
+ # Use handle_file to properly handle the image upload
176
+ result = client.predict(
177
+ input_image=handle_file(input_image),
178
+ api_name="/image_upscale_interface"
179
+ )
180
+
181
+ # Extract the image URL from the HTML response
182
+ if isinstance(result, tuple) and len(result) > 0:
183
+ html_string = result[0]
184
+ match = re.search(r"src='([^']+)'", html_string)
185
+ if match:
186
+ image_url = match.group(1)
187
+ return image_url
188
+ else:
189
+ return "https://via.placeholder.com/400x200?text=Error:Image+Not+Found"
190
+ else:
191
+ return str(result)
192
+
193
+ except Exception as e:
194
+ return f"Error upscaling image: {str(e)}"
195
+
196
+ # Define a Python function for video generation from images
197
+ def generate_video(first_frame, end_frame, prompt, duration, height, width, enhance_prompt, seed, randomize_seed, camera_lora):
198
+ """
199
+ Generate a video from start and end frames using the LTX-2-TURBO API.
200
+
201
+ Args:
202
+ first_frame (str): Path to the starting frame image
203
+ end_frame (str): Path to the ending frame image
204
+ prompt (str): Text description of the video to generate
205
+ duration (int): Duration of the video in seconds
206
+ height (int): Height of the video in pixels
207
+ width (int): Width of the video in pixels
208
+ enhance_prompt (bool): Whether to enhance the prompt with AI
209
+ seed (int): Random seed for reproducibility
210
+ randomize_seed (bool): Whether to randomize the seed
211
+ camera_lora (str): Camera LoRA setting
212
+
213
+ Returns:
214
+ str: Path to the generated video or error message
215
+ """
216
+ try:
217
+ if first_frame is None or end_frame is None:
218
+ return "Please upload both start and end frame images"
219
+
220
+ if not prompt.strip():
221
+ return "Please enter a video prompt"
222
+
223
+ # Use handle_file to properly handle the image uploads
224
+ result = video_client.predict(
225
+ first_frame=handle_file(first_frame),
226
+ end_frame=handle_file(end_frame),
227
+ prompt=prompt,
228
+ duration=duration,
229
+ input_video=None,
230
+ generation_mode="Image-to-Video",
231
+ enhance_prompt=enhance_prompt,
232
+ seed=seed,
233
+ randomize_seed=randomize_seed,
234
+ height=height,
235
+ width=width,
236
+ camera_lora=camera_lora,
237
+ audio_path=None,
238
+ api_name="/generate_video"
239
+ )
240
+
241
+ # Return the result directly (should be a video file path)
242
+ if result:
243
+ return result
244
+ else:
245
+ return "Error: No video generated"
246
+
247
+ except Exception as e:
248
+ return f"Error generating video: {str(e)}"
249
+
250
+ # Create a Gradio application using gr.Blocks for more granular control.
251
+ with gr.Blocks(
252
+ title='Omni Image Editor with Gradio',
253
+ theme=gr.themes.Soft()
254
+ ) as demo:
255
+ gr.Markdown("# Omni Image Editor Studio")
256
+ gr.Markdown("Generate images from text descriptions or edit existing images with AI-powered tools.")
257
+
258
+ with gr.Tabs():
259
+ # GPU-Accelerated Text-to-Image Tab
260
+ with gr.TabItem("GPU Image Generator"):
261
+ gr.Markdown("### High-Quality Image Generation (Local GPU)")
262
+ gr.Markdown("Generate high-quality images using Flux model running locally on your GPU. Faster and more private than API-based generation.")
263
+
264
+ with gr.Row():
265
+ with gr.Column():
266
+ gpu_prompt_input = gr.Textbox(
267
+ label='Image Description',
268
+ placeholder='e.g., A serene landscape with mountains and aurora borealis, photorealistic, 4K quality',
269
+ lines=3
270
+ )
271
+
272
+ with gr.Row():
273
+ with gr.Column():
274
+ gpu_height = gr.Slider(
275
+ label='Height (pixels)',
276
+ minimum=256,
277
+ maximum=1024,
278
+ value=768,
279
+ step=64
280
+ )
281
+ with gr.Column():
282
+ gpu_width = gr.Slider(
283
+ label='Width (pixels)',
284
+ minimum=256,
285
+ maximum=1024,
286
+ value=768,
287
+ step=64
288
+ )
289
+
290
+ with gr.Row():
291
+ with gr.Column():
292
+ gpu_steps = gr.Slider(
293
+ label='Inference Steps',
294
+ minimum=1,
295
+ maximum=50,
296
+ value=20,
297
+ step=1
298
+ )
299
+ with gr.Column():
300
+ gpu_num_images = gr.Slider(
301
+ label='Number of Images',
302
+ minimum=1,
303
+ maximum=4,
304
+ value=1,
305
+ step=1
306
+ )
307
+
308
+ with gr.Row():
309
+ with gr.Column():
310
+ gpu_seed = gr.Number(
311
+ label='Seed',
312
+ value=0,
313
+ precision=0
314
+ )
315
+ with gr.Column():
316
+ gpu_randomize = gr.Checkbox(
317
+ label='Randomize Seed',
318
+ value=True
319
+ )
320
+
321
+ with gr.Row():
322
+ gpu_generate_btn = gr.Button("🖼️ Generate Images (GPU)", variant="primary", size='lg')
323
+
324
+ gpu_seed_output = gr.Number(label='Seed Used', interactive=False)
325
+ gpu_generated_images = gr.Gallery(label='Generated Images', show_label=True, columns=2)
326
+
327
+ # Bind the generate_image_gpu function to the button click event
328
+ gpu_generate_btn.click(
329
+ fn=generate_image_gpu,
330
+ inputs=[
331
+ gpu_prompt_input,
332
+ gpu_height,
333
+ gpu_width,
334
+ gpu_steps,
335
+ gpu_seed,
336
+ gpu_randomize,
337
+ gpu_num_images
338
+ ],
339
+ outputs=[gpu_generated_images, gpu_seed_output]
340
+ )
341
+
342
+ # Text-to-Image Tab (API-based)
343
+ with gr.TabItem("Text to Image Generator"):
344
+ gr.Markdown("### Generate Images from Text")
345
+ gr.Markdown("Describe the image you want to generate in detail for best results.")
346
+
347
+ with gr.Row():
348
+ with gr.Column():
349
+ prompt_input = gr.Textbox(
350
+ label='Image Description',
351
+ placeholder='e.g., A futuristic city at sunset with flying cars, neon lights, cyberpunk style, high quality',
352
+ lines=3
353
+ )
354
+ generate_btn = gr.Button("🎨 Generate Image", variant="primary")
355
+
356
+ generated_image = gr.Image(label='Generated Image', type='filepath')
357
+
358
+ # Bind the generate_image function to the button click event
359
+ generate_btn.click(
360
+ fn=generate_image,
361
+ inputs=[prompt_input],
362
+ outputs=[generated_image]
363
+ )
364
+
365
+ # Image Editing Tab
366
+ with gr.TabItem("Image Editor"):
367
+ gr.Markdown("### Edit Images with AI")
368
+ gr.Markdown("Upload an image and describe the changes you want to make.")
369
+
370
+ with gr.Row():
371
+ with gr.Column():
372
+ input_image = gr.Image(
373
+ label='Upload Image',
374
+ type='filepath'
375
+ )
376
+
377
+ with gr.Row():
378
+ with gr.Column():
379
+ edit_prompt = gr.Textbox(
380
+ label='Edit Instructions',
381
+ placeholder='e.g., Change the sky to sunset colors, add stars, increase contrast',
382
+ lines=3
383
+ )
384
+ edit_btn = gr.Button("✨ Edit Image", variant="primary")
385
+
386
+ edited_image = gr.Image(label='Edited Image', type='filepath')
387
+
388
+ # Bind the edit_image function to the button click event
389
+ edit_btn.click(
390
+ fn=edit_image,
391
+ inputs=[input_image, edit_prompt],
392
+ outputs=[edited_image]
393
+ )
394
+
395
+ # Image Upscaling Tab
396
+ with gr.TabItem("Image Upscaler"):
397
+ gr.Markdown("### Upscale Images to Higher Resolution")
398
+ gr.Markdown("Upload an image and enhance it to higher resolution using AI-powered upscaling.")
399
+
400
+ with gr.Row():
401
+ with gr.Column():
402
+ upscale_input = gr.Image(
403
+ label='Upload Image to Upscale',
404
+ type='filepath'
405
+ )
406
+ upscale_btn = gr.Button("⬆️ Upscale Image", variant="primary")
407
+
408
+ upscaled_image = gr.Image(label='Upscaled Image', type='filepath')
409
+
410
+ # Bind the upscale_image function to the button click event
411
+ upscale_btn.click(
412
+ fn=upscale_image,
413
+ inputs=[upscale_input],
414
+ outputs=[upscaled_image]
415
+ )
416
+
417
+ # Video Generation Tab
418
+ with gr.TabItem("Video Generator"):
419
+ gr.Markdown("### Generate Videos from Images")
420
+ gr.Markdown("Upload start and end frame images and describe the motion you want to create.")
421
+
422
+ with gr.Row():
423
+ with gr.Column():
424
+ video_first_frame = gr.Image(
425
+ label='First Frame (Start Image)',
426
+ type='filepath'
427
+ )
428
+ with gr.Column():
429
+ video_end_frame = gr.Image(
430
+ label='End Frame (Final Image)',
431
+ type='filepath'
432
+ )
433
+
434
+ with gr.Row():
435
+ with gr.Column():
436
+ video_prompt = gr.Textbox(
437
+ label='Video Description',
438
+ placeholder='e.g., Make this image come alive with cinematic motion, smooth camera pan, 4K quality',
439
+ lines=3
440
+ )
441
+
442
+ with gr.Row():
443
+ with gr.Column():
444
+ video_duration = gr.Slider(
445
+ label='Duration (seconds)',
446
+ minimum=1,
447
+ maximum=10,
448
+ value=5,
449
+ step=1
450
+ )
451
+ with gr.Column():
452
+ video_height = gr.Slider(
453
+ label='Height (pixels)',
454
+ minimum=256,
455
+ maximum=1024,
456
+ value=512,
457
+ step=64
458
+ )
459
+ with gr.Column():
460
+ video_width = gr.Slider(
461
+ label='Width (pixels)',
462
+ minimum=256,
463
+ maximum=1024,
464
+ value=768,
465
+ step=64
466
+ )
467
+
468
+ with gr.Row():
469
+ with gr.Column():
470
+ video_enhance = gr.Checkbox(
471
+ label='Enhance Prompt with AI',
472
+ value=True
473
+ )
474
+ with gr.Column():
475
+ video_randomize = gr.Checkbox(
476
+ label='Randomize Seed',
477
+ value=True
478
+ )
479
+ with gr.Column():
480
+ video_seed = gr.Number(
481
+ label='Seed',
482
+ value=10,
483
+ precision=0
484
+ )
485
+
486
+ with gr.Row():
487
+ with gr.Column():
488
+ video_camera = gr.Dropdown(
489
+ label='Camera LoRA',
490
+ choices=['No LoRA', 'Pan Left', 'Pan Right', 'Zoom In', 'Zoom Out', 'Rotate CW', 'Rotate CCW'],
491
+ value='No LoRA'
492
+ )
493
+
494
+ with gr.Row():
495
+ video_generate_btn = gr.Button("🎬 Generate Video", variant="primary", size='lg')
496
+
497
+ generated_video = gr.Video(label='Generated Video')
498
+
499
+ # Bind the generate_video function to the button click event
500
+ video_generate_btn.click(
501
+ fn=generate_video,
502
+ inputs=[
503
+ video_first_frame,
504
+ video_end_frame,
505
+ video_prompt,
506
+ video_duration,
507
+ video_height,
508
+ video_width,
509
+ video_enhance,
510
+ video_seed,
511
+ video_randomize,
512
+ video_camera
513
+ ],
514
+ outputs=[generated_video]
515
+ )
516
+
517
+ # Launch the Gradio application.
518
+ if __name__ == "__main__":
519
+ demo.launch(share=True)