ovi054 commited on
Commit
cc9f5c8
·
verified ·
1 Parent(s): ef462e1

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +170 -0
app.py ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import io
3
+ import random
4
+ import requests
5
+ import gradio as gr
6
+ import numpy as np
7
+ from PIL import Image
8
+
9
+
10
+ MAX_SEED = np.iinfo(np.int32).max
11
+
12
+ API_TOKEN = os.getenv("HF_TOKEN")
13
+ headers = {"Authorization": f"Bearer {API_TOKEN}"}
14
+ timeout = 100
15
+
16
+
17
+ def split_image(input_image, num_splits=4):
18
+ output_images = []
19
+
20
+ # Define the coordinates for the 2x2 grid (left-to-right, top-to-bottom)
21
+ boxes = [
22
+ (0, 0, 512, 512), # Top-left
23
+ (512, 0, 1024, 512), # Top-right
24
+ (0, 512, 512, 1024), # Bottom-left
25
+ (512, 512, 1024, 1024) # Bottom-right
26
+ ]
27
+
28
+ # Crop the input image based on the defined boxes
29
+ for box in boxes:
30
+ output_images.append(input_image.crop(box))
31
+
32
+ return output_images
33
+
34
+
35
+ # Function to export split images to GIF
36
+ def export_to_gif(images, output_path, fps=4):
37
+ # Calculate duration per frame in milliseconds based on fps
38
+ duration = int(1000 / fps)
39
+
40
+ # Create a GIF from the list of images
41
+ images[0].save(
42
+ output_path,
43
+ save_all=True,
44
+ append_images=images[1:],
45
+ duration=duration, # Duration between frames
46
+ loop=0 # Loop forever
47
+ )
48
+
49
+
50
+ def predict(prompt, seed=-1, randomize_seed=True, guidance_scale=3.5, num_inference_steps=28, lora_id="black-forest-labs/FLUX.1-dev", progress=gr.Progress(track_tqdm=True)):
51
+ prompt_template = f"""a 2x2 total 4 grid of frames, showing consecutive stills from a looped gif of {prompt}"""
52
+
53
+ if lora_id.strip() == "" or lora_id == None:
54
+ lora_id = "black-forest-labs/FLUX.1-dev"
55
+
56
+ if randomize_seed:
57
+ seed = random.randint(0, MAX_SEED)
58
+
59
+ key = random.randint(0, 999)
60
+
61
+ API_URL = "https://api-inference.huggingface.co/models/"+ lora_id.strip()
62
+
63
+ API_TOKEN = random.choice([os.getenv("HF_TOKEN")])
64
+ headers = {"Authorization": f"Bearer {API_TOKEN}"}
65
+
66
+ payload = {
67
+ "inputs": prompt_template,
68
+ "steps": num_inference_steps,
69
+ "cfg_scale": guidance_scale,
70
+ "seed": seed,
71
+ }
72
+
73
+ response = requests.post(API_URL, headers=headers, json=payload, timeout=timeout)
74
+ if response.status_code != 200:
75
+ print(f"Error: Failed to get image. Response status: {response.status_code}")
76
+ print(f"Response content: {response.text}")
77
+ if response.status_code == 503:
78
+ raise gr.Error(f"{response.status_code} : The model is being loaded")
79
+ raise gr.Error(f"{response.status_code}")
80
+
81
+ try:
82
+ image_bytes = response.content
83
+ image = Image.open(io.BytesIO(image_bytes))
84
+ print(f'\033[1mGeneration {key} completed!\033[0m ({prompt})')
85
+
86
+ split_images = split_image(image, num_splits=4)
87
+
88
+ # Path to save the GIF
89
+ gif_path = "output.gif"
90
+
91
+ # Export the split images to GIF
92
+ export_to_gif(split_images, gif_path, fps=4)
93
+ return gif_path, image, seed
94
+ except Exception as e:
95
+ print(f"Error when trying to open the image: {e}")
96
+ return None
97
+
98
+
99
+ demo = gr.Interface(fn=predict, inputs="text", outputs="image")
100
+
101
+ css="""
102
+ #col-container {
103
+ margin: 0 auto;
104
+ max-width: 520px;
105
+ }
106
+ #stills{max-height:160px}
107
+ """
108
+ examples = [
109
+ "a cat waving its paws in the air",
110
+ "a panda moving their hips from side to side",
111
+ "a flower going through the process of blooming"
112
+ ]
113
+
114
+ with gr.Blocks(css=css) as demo:
115
+ with gr.Column(elem_id="col-container"):
116
+ gr.Markdown("# FLUX Gif Generator")
117
+ gr.Markdown("Create GIFs with Flux-dev. Based on @dn6's [space](https://huggingface.co/spaces/dn6/FLUX-GIFs) and @fofr's [tweet](https://x.com/fofrAI/status/1828910395962343561).")
118
+ gr.Markdown("Add LoRA (if needed) in Advanced Settings. For better results, include a description of the motion in your prompt.")
119
+ # gr.Markdown("For better results include a description of the motion in your prompt")
120
+ # with gr.Row():
121
+ # with gr.Column():
122
+ with gr.Row():
123
+ prompt = gr.Text(label="Prompt", show_label=False, max_lines=4, show_copy_button = True, placeholder="Enter your prompt", container=False)
124
+ submit = gr.Button("Submit", scale=0)
125
+
126
+ output = gr.Image(label="GIF", show_label=False)
127
+ output_stills = gr.Image(label="stills", show_label=False, elem_id="stills")
128
+ with gr.Accordion("Advanced Settings", open=False):
129
+ custom_lora = gr.Textbox(label="Custom LoRA", info="LoRA Hugging Face path (optional)", placeholder="multimodalart/vintage-ads-flux")
130
+ seed = gr.Slider(
131
+ label="Seed",
132
+ minimum=0,
133
+ maximum=MAX_SEED,
134
+ step=1,
135
+ value=0,
136
+ )
137
+
138
+ randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
139
+
140
+ with gr.Row():
141
+ guidance_scale = gr.Slider(
142
+ label="Guidance Scale",
143
+ minimum=1,
144
+ maximum=15,
145
+ step=0.1,
146
+ value=3.5,
147
+ )
148
+ num_inference_steps = gr.Slider(
149
+ label="Number of inference steps",
150
+ minimum=1,
151
+ maximum=50,
152
+ step=1,
153
+ value=28,
154
+ )
155
+
156
+ gr.Examples(
157
+ examples=examples,
158
+ fn=predict,
159
+ inputs=[prompt],
160
+ outputs=[output, output_stills, seed],
161
+ cache_examples="lazy"
162
+ )
163
+ gr.on(
164
+ triggers=[submit.click, prompt.submit],
165
+ fn=predict,
166
+ inputs=[prompt, seed, randomize_seed, guidance_scale, num_inference_steps, custom_lora],
167
+ outputs = [output, output_stills, seed]
168
+ )
169
+
170
+ demo.launch()