|
import random |
|
import tempfile |
|
|
|
import gradio as gr |
|
|
|
from main import create_code_gif |
|
|
|
|
|
def _create_code_gif( |
|
code: str, |
|
style_name: str = "monokai", |
|
start_color: str = "#FF6B6B", |
|
end_color: str = "#4ECDC4", |
|
title: str = "Code GIF", |
|
favicon: str = "https://huggingface.co/front/assets/huggingface_logo-noborder.svg", |
|
photo: str = "https://photo.jpg", |
|
aspect_ratio: float = 16 / 9, |
|
): |
|
|
|
def parse_color(color: str) -> tuple: |
|
if color.startswith("rgba"): |
|
|
|
values = color.strip("rgba()").split(",") |
|
return tuple(int(float(x)) for x in values[:3]) |
|
else: |
|
|
|
return tuple(int(color.lstrip("#")[i : i + 2], 16) for i in (0, 2, 4)) |
|
|
|
start_rgb = parse_color(start_color) |
|
end_rgb = parse_color(end_color) |
|
|
|
with tempfile.NamedTemporaryFile(suffix=".gif", delete=False) as tmp: |
|
create_code_gif( |
|
code=code, |
|
output_file=tmp.name, |
|
style=style_name, |
|
gradient_start=start_rgb, |
|
gradient_end=end_rgb, |
|
line_numbers=False, |
|
title=title, |
|
filename="code.py", |
|
favicon=favicon, |
|
photo=photo, |
|
aspect_ratio=aspect_ratio, |
|
) |
|
return tmp.name |
|
|
|
|
|
code_placeholder = """ |
|
def main(): |
|
print("Hello, World!") |
|
|
|
|
|
if __name__ == "__main__": |
|
main() |
|
""" |
|
|
|
|
|
|
|
def get_random_color(): |
|
return f"#{random.randint(0, 0xFFFFFF):06x}" |
|
|
|
|
|
start_color = get_random_color() |
|
end_color = get_random_color() |
|
|
|
with gr.Blocks(title="Python Code GIF Generator") as demo: |
|
gr.Markdown("# Python Code GIF Generator") |
|
gr.Markdown("Generate animated code GIFs with customizable styles and effects") |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
gr.Markdown("### Input Settings") |
|
code = gr.Code( |
|
label="Code", lines=10, language="python", value=code_placeholder |
|
) |
|
title = gr.Textbox( |
|
label="Title", value="Code GIF", placeholder="My animated code" |
|
) |
|
with gr.Row(variant="compact"): |
|
style = gr.Dropdown( |
|
choices=[ |
|
"monokai", |
|
"dracula", |
|
"nord-darker", |
|
"gruvbox-dark", |
|
"solarized-dark", |
|
"one-dark", |
|
"github-dark", |
|
"material", |
|
"zenburn", |
|
"vs-dark", |
|
"tomorrow-night", |
|
"paraiso-dark", |
|
"native", |
|
"fruity", |
|
"vim", |
|
], |
|
label="Style", |
|
value="monokai", |
|
) |
|
aspect_ratio = gr.Dropdown( |
|
label="Aspect Ratio", |
|
choices=[("Portrait (9:16)", 9 / 16), ("Landscape (16:9)", 16 / 9)], |
|
value=9 / 16, |
|
type="value", |
|
) |
|
with gr.Row(variant="compact"): |
|
start_color_picker = gr.ColorPicker( |
|
label="Start Color", value=start_color |
|
) |
|
end_color_picker = gr.ColorPicker(label="End Color", value=end_color) |
|
refresh_colors = gr.Button("Refresh Colors") |
|
with gr.Row(): |
|
photo = gr.Textbox( |
|
label="Photo", |
|
value="https://www.indiewire.com/wp-content/uploads/2017/10/matrix-code.jpg", |
|
placeholder="https://www.indiewire.com/wp-content/uploads/2017/10/matrix-code.jpg", |
|
) |
|
favicon = gr.Textbox( |
|
label="Favicon", |
|
value="https://huggingface.co/front/assets/huggingface_logo-noborder.svg", |
|
placeholder="https://huggingface.co/front/assets/huggingface_logo-noborder.svg", |
|
) |
|
with gr.Row(): |
|
submit_btn = gr.Button("Generate GIF") |
|
|
|
|
|
with gr.Column(): |
|
gr.Markdown("### Generated Output") |
|
output_image = gr.Image(label="Generated GIF", type="filepath") |
|
|
|
submit_btn.click( |
|
fn=_create_code_gif, |
|
inputs=[ |
|
code, |
|
style, |
|
start_color_picker, |
|
end_color_picker, |
|
title, |
|
favicon, |
|
photo, |
|
aspect_ratio, |
|
], |
|
outputs=output_image, |
|
) |
|
gr.on( |
|
[refresh_colors.click, demo.load], |
|
fn=lambda: (get_random_color(), get_random_color()), |
|
inputs=[], |
|
outputs=[start_color_picker, end_color_picker], |
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
demo.launch() |
|
|