Export to *.gif
Browse files
app.py
CHANGED
|
@@ -10,7 +10,7 @@ from pathlib import Path
|
|
| 10 |
from typing import Optional
|
| 11 |
|
| 12 |
from diffusers import StableVideoDiffusionPipeline
|
| 13 |
-
from diffusers.utils import export_to_video
|
| 14 |
from PIL import Image
|
| 15 |
|
| 16 |
fps25Pipe = StableVideoDiffusionPipeline.from_pretrained(
|
|
@@ -63,9 +63,18 @@ def animate(
|
|
| 63 |
|
| 64 |
os.makedirs(output_folder, exist_ok=True)
|
| 65 |
base_count = len(glob(os.path.join(output_folder, "*." + video_format)))
|
| 66 |
-
|
| 67 |
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
end = time.time()
|
| 70 |
secondes = int(end - start)
|
| 71 |
minutes = math.floor(secondes / 60)
|
|
@@ -79,7 +88,7 @@ def animate(
|
|
| 79 |
((str(minutes) + " min, ") if hours != 0 or minutes != 0 else "") + \
|
| 80 |
str(secondes) + " sec."
|
| 81 |
|
| 82 |
-
return gr.update(value=video_path, format=video_format), gr.update(value=
|
| 83 |
|
| 84 |
@spaces.GPU(duration=120)
|
| 85 |
def animate_on_gpu(
|
|
@@ -131,8 +140,7 @@ def resize_image(image, output_size=(1024, 576)):
|
|
| 131 |
bottom = (new_height + output_size[1]) / 2
|
| 132 |
|
| 133 |
# Crop the image
|
| 134 |
-
|
| 135 |
-
return cropped_image
|
| 136 |
|
| 137 |
def reset():
|
| 138 |
return [
|
|
@@ -167,7 +175,7 @@ with gr.Blocks() as demo:
|
|
| 167 |
motion_bucket_id = gr.Slider(label="Motion bucket id", info="Controls how much motion to add/remove from the image", value=127, minimum=1, maximum=255)
|
| 168 |
noise_aug_strength = gr.Slider(label="Noise strength", info="The noise to add", value=0.1, minimum=0, maximum=1, step=0.1)
|
| 169 |
decoding_t = gr.Slider(label="Decoding", info="Number of frames decoded at a time; this eats more VRAM; reduce if necessary", value=3, minimum=1, maximum=5, step=1)
|
| 170 |
-
video_format = gr.Radio([["*.mp4", "mp4"]], label="Video format for result", info="File extention", value="mp4", interactive=True)
|
| 171 |
frame_format = gr.Radio([["*.webp", "webp"], ["*.png", "png"], ["*.jpeg", "jpeg"], ["*.gif (unanimated)", "gif"], ["*.bmp", "bmp"]], label="Image format for frames", info="File extention", value="webp", interactive=True)
|
| 172 |
version = gr.Radio([["Auto", "auto"], ["🏃🏻♀️ SVD (trained on 14 f/s)", "svd"], ["🏃🏻♀️💨 SVD-XT (trained on 25 f/s)", "svdxt"]], label="Model", info="Trained model", value="auto", interactive=True)
|
| 173 |
seed = gr.Slider(label="Seed", value=42, randomize=True, minimum=0, maximum=max_64_bit_int, step=1)
|
|
@@ -177,9 +185,10 @@ with gr.Blocks() as demo:
|
|
| 177 |
reset_btn = gr.Button(value="🧹 Reinit page", variant="stop", elem_id="reset_button", visible = False)
|
| 178 |
|
| 179 |
with gr.Column():
|
| 180 |
-
|
|
|
|
| 181 |
download_button = gr.DownloadButton(label="💾 Download video", visible=False)
|
| 182 |
-
information_msg = gr.HTML(visible
|
| 183 |
gallery = gr.Gallery(label="Generated frames", visible=False)
|
| 184 |
|
| 185 |
image.upload(fn=resize_image, inputs=image, outputs=image, queue=False)
|
|
@@ -195,7 +204,8 @@ with gr.Blocks() as demo:
|
|
| 195 |
frame_format,
|
| 196 |
version
|
| 197 |
], outputs=[
|
| 198 |
-
|
|
|
|
| 199 |
download_button,
|
| 200 |
gallery,
|
| 201 |
seed,
|
|
@@ -223,7 +233,7 @@ with gr.Blocks() as demo:
|
|
| 223 |
["Examples/Town.jpeg", 42, True, 127, 25, 0.1, 3, "mp4", "png", "auto"]
|
| 224 |
],
|
| 225 |
inputs=[image, seed, randomize_seed, motion_bucket_id, fps_id, noise_aug_strength, decoding_t, video_format, frame_format, version],
|
| 226 |
-
outputs=[
|
| 227 |
fn=animate,
|
| 228 |
run_on_click=True,
|
| 229 |
cache_examples=False,
|
|
|
|
| 10 |
from typing import Optional
|
| 11 |
|
| 12 |
from diffusers import StableVideoDiffusionPipeline
|
| 13 |
+
from diffusers.utils import export_to_video, export_to_gif
|
| 14 |
from PIL import Image
|
| 15 |
|
| 16 |
fps25Pipe = StableVideoDiffusionPipeline.from_pretrained(
|
|
|
|
| 63 |
|
| 64 |
os.makedirs(output_folder, exist_ok=True)
|
| 65 |
base_count = len(glob(os.path.join(output_folder, "*." + video_format)))
|
| 66 |
+
result_path = os.path.join(output_folder, f"{base_count:06d}." + video_format)
|
| 67 |
|
| 68 |
+
if video_format == "gif":
|
| 69 |
+
video_path = None
|
| 70 |
+
gif_path = result_path
|
| 71 |
+
video_format = None
|
| 72 |
+
export_to_gif(image=frames, output_gif_path=gif_path, fps=fps_id)
|
| 73 |
+
else:
|
| 74 |
+
video_path = result_path
|
| 75 |
+
gif_path = None
|
| 76 |
+
export_to_video(frames, video_path, fps=fps_id)
|
| 77 |
+
|
| 78 |
end = time.time()
|
| 79 |
secondes = int(end - start)
|
| 80 |
minutes = math.floor(secondes / 60)
|
|
|
|
| 88 |
((str(minutes) + " min, ") if hours != 0 or minutes != 0 else "") + \
|
| 89 |
str(secondes) + " sec."
|
| 90 |
|
| 91 |
+
return gr.update(value=video_path, format=video_format), gr.update(value=gif_path, visible=video_format == "gif"), gr.update(value=result_path, visible=True), gr.update(label="Generated frames in *." + frame_format + " format", format = frame_format, value = frames, visible=True), seed, gr.update(value = information, visible = True), gr.update(visible=True)
|
| 92 |
|
| 93 |
@spaces.GPU(duration=120)
|
| 94 |
def animate_on_gpu(
|
|
|
|
| 140 |
bottom = (new_height + output_size[1]) / 2
|
| 141 |
|
| 142 |
# Crop the image
|
| 143 |
+
return resized_image.crop((left, top, right, bottom))
|
|
|
|
| 144 |
|
| 145 |
def reset():
|
| 146 |
return [
|
|
|
|
| 175 |
motion_bucket_id = gr.Slider(label="Motion bucket id", info="Controls how much motion to add/remove from the image", value=127, minimum=1, maximum=255)
|
| 176 |
noise_aug_strength = gr.Slider(label="Noise strength", info="The noise to add", value=0.1, minimum=0, maximum=1, step=0.1)
|
| 177 |
decoding_t = gr.Slider(label="Decoding", info="Number of frames decoded at a time; this eats more VRAM; reduce if necessary", value=3, minimum=1, maximum=5, step=1)
|
| 178 |
+
video_format = gr.Radio([["*.mp4", "mp4"], ["*.gif", "gif"]], label="Video format for result", info="File extention", value="mp4", interactive=True)
|
| 179 |
frame_format = gr.Radio([["*.webp", "webp"], ["*.png", "png"], ["*.jpeg", "jpeg"], ["*.gif (unanimated)", "gif"], ["*.bmp", "bmp"]], label="Image format for frames", info="File extention", value="webp", interactive=True)
|
| 180 |
version = gr.Radio([["Auto", "auto"], ["🏃🏻♀️ SVD (trained on 14 f/s)", "svd"], ["🏃🏻♀️💨 SVD-XT (trained on 25 f/s)", "svdxt"]], label="Model", info="Trained model", value="auto", interactive=True)
|
| 181 |
seed = gr.Slider(label="Seed", value=42, randomize=True, minimum=0, maximum=max_64_bit_int, step=1)
|
|
|
|
| 185 |
reset_btn = gr.Button(value="🧹 Reinit page", variant="stop", elem_id="reset_button", visible = False)
|
| 186 |
|
| 187 |
with gr.Column():
|
| 188 |
+
video_output = gr.Video(label="Generated video", autoplay=True)
|
| 189 |
+
gif_output = gr.Image(label="Generated video", format="gif", visible=False)
|
| 190 |
download_button = gr.DownloadButton(label="💾 Download video", visible=False)
|
| 191 |
+
information_msg = gr.HTML(visible=False)
|
| 192 |
gallery = gr.Gallery(label="Generated frames", visible=False)
|
| 193 |
|
| 194 |
image.upload(fn=resize_image, inputs=image, outputs=image, queue=False)
|
|
|
|
| 204 |
frame_format,
|
| 205 |
version
|
| 206 |
], outputs=[
|
| 207 |
+
video_output,
|
| 208 |
+
gif_output,
|
| 209 |
download_button,
|
| 210 |
gallery,
|
| 211 |
seed,
|
|
|
|
| 233 |
["Examples/Town.jpeg", 42, True, 127, 25, 0.1, 3, "mp4", "png", "auto"]
|
| 234 |
],
|
| 235 |
inputs=[image, seed, randomize_seed, motion_bucket_id, fps_id, noise_aug_strength, decoding_t, video_format, frame_format, version],
|
| 236 |
+
outputs=[video_output, gif_output, download_button, gallery, seed, information_msg, reset_btn],
|
| 237 |
fn=animate,
|
| 238 |
run_on_click=True,
|
| 239 |
cache_examples=False,
|