Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gradio UI #175

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# Gradio UI for Animated Drawings
I really love the Animated Drawings tool, but it was quite hard to explain how to use it to friends. This is why i decided to create this more convinient way using a Gradio Interface.

To utilize this tool, follow these simple steps:

### Setup and Starting the Gradio UI
0. Run the shell script "start_gradio.sh" in the terminal. It will install gradio and run the "gradio_script.py" script. open the localhost on your browser and start using it!

### Inside of the GUI
1. Input the directory path to your AnimatedDrawings folder.
2. Specify your desired output directory for the generated .yaml file.
3. Click the "Refresh" button to populate the drop-down menus for Character, Motion, and Target. This action will populate these fields based on the folder names in the .../AnimatedDrawings/examples/characters directory for Characters, filenames in the .../AnimatedDrawings/config/motion directory for Motion, and filenames in the .../AnimatedDrawings/config/retarget directory for Target.
4. Next, select your preferred export option - file only, video, or GIF. Choosing MP4 will present a preview directly in the Gradio interface.
5. Finally, click "Export" to generate and export your MVC .yaml files.

I hope you all find this tool beneficial and enjoyable to use. My next step will involve the Docker part of AnimatedDrawings, though I'm still familiarizing myself with it, so stay tuned for more developments!


### Demo Video
https://github.com/vensu-art/AnimatedDrawingsGradio/assets/116193678/107204cc-b4c4-42d0-8abf-510c5df4c46a


# Animated Drawings

![Sequence 02](https://user-images.githubusercontent.com/6675724/219223438-2c93f9cb-d4b5-45e9-a433-149ed76affa6.gif)
Expand Down
159 changes: 159 additions & 0 deletions gradio_script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import gradio as gr
import os
import subprocess


# Get the names of folders in a directory
def get_folder_names(directory):
return [d for d in os.listdir(directory) if os.path.isdir(os.path.join(directory, d))]

# Get the names of files in a directory
def get_file_names(directory):
return [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))]


# Function to write MVC
def writeMVC(character_folder, motion_file, target_file, export_radio, output_path, video_path):
# Sets the video format to None, MP4 or Gif
export_format = ""
if export_radio == 1:
export_format = """
controller:
MODE: video_render
OUTPUT_VIDEO_PATH: {output_video_path}/video.mp4
OUTPUT_VIDEO_CODEC: avc1
""".format(
output_video_path=video_path
)
elif export_radio == 2:
export_format = """
controller:
MODE: video_render
OUTPUT_VIDEO_PATH: {output_video_path}/video.gif
""".format(
output_video_path=video_path
)

updated_config = export_format + """
scene:
ANIMATED_CHARACTERS:
- character_cfg: examples/characters/{character_cfg}/char_cfg.yaml
motion_cfg: examples/config/motion/{motion_cfg}
retarget_cfg: examples/config/retarget/{retarget_cfg}
""".format(
character_cfg=character_folder,
motion_cfg=motion_file,
retarget_cfg=target_file,
)

config_filename = os.path.join(output_path, "custom_config.yaml")
with open(config_filename, "w") as f:
f.write(updated_config)


# Run the script to generate
cmd = ['python', '-c',
"""
from animated_drawings import render
render.start('{}')
""".format(config_filename)]

subprocess.run(cmd)


# If the video was generated, return it.
if export_radio == 1:
video_path = os.path.join(video_path, "video.mp4")
if os.path.exists(video_path):
return video_path

return


# Function to refresh dropdown options
def refresh_options(directory):
character_folder_path = os.path.join(directory, 'examples/characters')
motion_file_path = os.path.join(directory, 'examples/config/motion')
target_file_path = os.path.join(directory, 'examples/config/retarget')

character_choices = get_folder_names(character_folder_path)
motion_choices = get_file_names(motion_file_path)
target_choices = get_file_names(target_file_path)

# Debug
# print(character_choices)
# print(motion_choices)
# print(target_choices)

return character_dropdown.update(choices=character_choices), motion_dropdown.update(choices=motion_choices), target_dropdown.update(choices=target_choices), gr.update(visible=True)


# Variables for Gradio
character_choices = []
motion_choices = []
target_choices = []


# Gradio UI
with gr.Blocks() as iface:
with gr.Row():
output_video = gr.Video(label="Animation")

with gr.Row():
directory_path = gr.Textbox(label="Directory", info="/Users/.../AnimatedDrawings")
output_path = gr.Textbox(label="Output Path Yaml", info="/Users/.../your_yaml_folder")


with gr.Row():
character_dropdown = gr.Dropdown(choices=character_choices, label="Character")
motion_dropdown = gr.Dropdown(choices=motion_choices, label="Motion")
target_dropdown = gr.Dropdown(choices=target_choices, label="Target")
refresh_button = gr.Button("Refresh")

with gr.Row():
export_radio = gr.Radio(["None", "MP4", "GIF"], type="index", label="Export", info="Choose the export format")
video_path = gr.Textbox(label="Output Path Video", info="/Users/.../your_video_folder")


with gr.Row():
submit = gr.Button("Export")

# Gradio Actions
submit.click(writeMVC, [character_dropdown, motion_dropdown, target_dropdown, export_radio, directory_path, video_path], [output_video])
refresh_button.click(refresh_options, directory_path, [character_dropdown, motion_dropdown, target_dropdown]) #, [character_folder, motion_file, target_file]

# Launch Gradio as Web UI
iface.launch()




# Examples from the provided yaml files
"""
# Define the output format GIF or MP4
controller:
MODE: video_render
OUTPUT_VIDEO_PATH: ./video.mp4
OUTPUT_VIDEO_CODEC: avc1

controller:
MODE: video_render
OUTPUT_VIDEO_PATH: ./video.gif

# Define the characters, motion and target
scene:
ANIMATED_CHARACTERS:
- character_cfg: examples/characters/char1/char_cfg.yaml
motion_cfg: examples/config/motion/dab.yaml
retarget_cfg: examples/config/retarget/fair1_ppf_duo1.yaml

# Define View and Background
view:
CAMERA_POS: [0.1, 1.3, 2.7]
WINDOW_DIMENSIONS: [300, 400]
BACKGROUND_IMAGE: examples/characters/char4/background.png

view:
CAMERA_POS: [2.0, 0.7, 8.0]
CAMERA_FWD: [0.0, 0.5, 8.0]
"""
22 changes: 22 additions & 0 deletions start_gradio.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# start_gradio.sh

#!/bin/bash

# check if gradio is installed
pip list | grep gradio &> /dev/null
if [ $? != 0 ]; then
echo "Gradio not found. Installing Gradio..."
pip install gradio
fi

# check if python3 is installed
command -v python3 >/dev/null 2>&1 || {
echo >&2 "Python3 required but it's not installed. Installing Python3...";
brew install python3;
}

# navigate to the script's directory
cd "$(dirname "$0")"

# start the gradio script
python3 gradio_script.py