import gradio as gr from PIL import Image import tempfile def reverse(input_path, frames_per_second): # Open the GIF file gif = Image.open(input_path) # Get the number of frames in the GIF num_frames = gif.n_frames # Create a list to hold the reversed frames reversed_frames = [] # Iterate through the frames in reverse order for frame_number in range(num_frames, 0, -1): gif.seek(frame_number - 1) frame = gif.copy() reversed_frames.append(frame) # Interesting blur effect on gifs with transparent background if 'duration' not in gif.info: # Default is 8 frames per second from AnimatedDiff duration = frames_per_second * num_frames gif.info['duration'] = duration # Save the reversed frames as a new GIF with tempfile.NamedTemporaryFile(suffix=".gif", delete=False) as temp_file: temp_filename = temp_file.name reversed_frames[0].save(temp_filename, save_all=True, append_images=reversed_frames[1:], duration=gif.info['duration'], loop=0) return temp_filename def reverse_gifs(input_paths, frames_per_second): if input_paths is None: return None, None input_paths = [f.name for f in input_paths] temp_filenames = [] for input_path in input_paths: temp_filenames.append(reverse(input_path, frames_per_second)) return input_paths, temp_filenames with gr.Blocks(theme='gstaff/sketch') as demo: gr.Markdown(value='# GIF Reversing Tool') with gr.Row(): with gr.Column(scale=1): gr.Markdown('## Load animated gifs to reverse') image_in = gr.Files(label="Input Gif Files", type='file', file_types=['.gif']) frame_rate = gr.Number(label="Frames per Second to use (if not in gif metadata)", value=8, minimum=1, maximum=360, step=1, interactive=True) image_display = gr.Gallery(label="Input Images", interactive=False) with gr.Column(scale=1): gr.Markdown('## View the reversed gif') image_out = gr.Gallery(label="Reversed Gif Images") clear_button = gr.ClearButton(components=[image_in]) image_in.change(reverse_gifs, [image_in, frame_rate], [image_display, image_out]) gr.Examples(examples=[[['./example.gif'], 8]], inputs=[image_in, frame_rate], outputs=[image_display, image_out], fn=reverse_gifs, cache_examples=True) with gr.Accordion('Developer Notes:', open=False): gr.Markdown('This gif reverser is a simple utility I made for myself.\n\n' 'The default of 8 frames per second works for the default settings of [AnimateDiff](https://github.com/continue-revolution/sd-webui-animatediff).\n\n' 'Future enhancements could be to auto-determine the framerate when otherwise not available in the gif metadata.') if __name__ == '__main__': demo.launch()