|
|
import gradio as gr |
|
|
import ascii_magic |
|
|
from PIL import Image |
|
|
|
|
|
def sanitize_ascii_string(ascii_str): |
|
|
replacements = { |
|
|
'<': '〈', |
|
|
'>': '〉', |
|
|
'&': '&', |
|
|
'"': '"', |
|
|
"'": ''', |
|
|
} |
|
|
for key, value in replacements.items(): |
|
|
ascii_str = ascii_str.replace(key, value) |
|
|
return ascii_str |
|
|
|
|
|
def normalize_lines(ascii_str): |
|
|
lines = ascii_str.split('\n') |
|
|
max_length = max(len(line) for line in lines) |
|
|
normalized_lines = [line.lstrip().ljust(max_length) for line in lines] |
|
|
return '\n'.join(normalized_lines) |
|
|
|
|
|
def convert_to_ascii(image, columns=100, font_size=10, width=256, height=256): |
|
|
if not isinstance(image, Image.Image): |
|
|
image = Image.open(image) |
|
|
|
|
|
|
|
|
image = image.convert('L') |
|
|
|
|
|
|
|
|
image = image.resize((width, height)) |
|
|
|
|
|
|
|
|
ascii_art = ascii_magic.from_pillow_image(image) |
|
|
ascii_html = ascii_art.to_html(columns=int(columns), monochrome=True) |
|
|
|
|
|
|
|
|
html_output = f""" |
|
|
<div style="white-space: pre; font-family: monospace; line-height: 1; font-size: {font_size}px; background-color: black; color: white;">{ascii_html}</div> |
|
|
""" |
|
|
|
|
|
|
|
|
lines = ascii_html.split("\n") |
|
|
if lines: |
|
|
lines[0] = lines[0].lstrip() |
|
|
ascii_html = "\n".join(lines) |
|
|
|
|
|
|
|
|
html_file_path = "ascii_art.html" |
|
|
with open(html_file_path, "w", encoding="utf-8") as file: |
|
|
file.write(html_output) |
|
|
|
|
|
return html_output, html_file_path |
|
|
|
|
|
with gr.Blocks(title="ASCII Art Converter") as demo: |
|
|
gr.Markdown("# Image to ASCII Art Converter By Sankritya Anand Rai") |
|
|
gr.Markdown("Convert images to detailed ASCII art. Adjust the resolution, font size, and image dimensions to control the output.") |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(scale=1): |
|
|
|
|
|
input_image = gr.Image( |
|
|
label="Input Image", |
|
|
type="pil", |
|
|
height=300 |
|
|
) |
|
|
|
|
|
with gr.Row(): |
|
|
resolution_slider = gr.Slider( |
|
|
minimum=32, |
|
|
maximum=200, |
|
|
value=100, |
|
|
step=1, |
|
|
label="Resolution (columns)", |
|
|
info="Higher values = more detail" |
|
|
) |
|
|
font_slider = gr.Slider( |
|
|
minimum=6, |
|
|
maximum=20, |
|
|
value=10, |
|
|
step=1, |
|
|
label="Font Size (px)", |
|
|
info="Adjust text size" |
|
|
) |
|
|
width_slider = gr.Slider( |
|
|
minimum=64, |
|
|
maximum=512, |
|
|
value=256, |
|
|
step=1, |
|
|
label="Image Width (px)", |
|
|
info="Adjust the width of the image" |
|
|
) |
|
|
height_slider = gr.Slider( |
|
|
minimum=64, |
|
|
maximum=512, |
|
|
value=256, |
|
|
step=1, |
|
|
label="Image Height (px)", |
|
|
info="Adjust the height of the image" |
|
|
) |
|
|
|
|
|
convert_btn = gr.Button("Convert to ASCII", variant="primary") |
|
|
|
|
|
with gr.Column(scale=1): |
|
|
|
|
|
output_html = gr.HTML(label="ASCII Art Output") |
|
|
download_html = gr.File(label="Download HTML File") |
|
|
|
|
|
|
|
|
convert_btn.click( |
|
|
fn=convert_to_ascii, |
|
|
inputs=[input_image, resolution_slider, font_slider, width_slider, height_slider], |
|
|
outputs=[output_html, download_html] |
|
|
) |
|
|
|
|
|
|
|
|
resolution_slider.change( |
|
|
fn=convert_to_ascii, |
|
|
inputs=[input_image, resolution_slider, font_slider, width_slider, height_slider], |
|
|
outputs=[output_html, download_html] |
|
|
) |
|
|
font_slider.change( |
|
|
fn=convert_to_ascii, |
|
|
inputs=[input_image, resolution_slider, font_slider, width_slider, height_slider], |
|
|
outputs=[output_html, download_html] |
|
|
) |
|
|
width_slider.change( |
|
|
fn=convert_to_ascii, |
|
|
inputs=[input_image, resolution_slider, font_slider, width_slider, height_slider], |
|
|
outputs=[output_html, download_html] |
|
|
) |
|
|
height_slider.change( |
|
|
fn=convert_to_ascii, |
|
|
inputs=[input_image, resolution_slider, font_slider, width_slider, height_slider], |
|
|
outputs=[output_html, download_html] |
|
|
) |
|
|
|
|
|
|
|
|
input_image.change( |
|
|
fn=convert_to_ascii, |
|
|
inputs=[input_image, resolution_slider, font_slider, width_slider, height_slider], |
|
|
outputs=[output_html, download_html] |
|
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch(share=True) |
|
|
|