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] # Remove leading whitespace and pad to max length
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)
# Convert image to grayscale
image = image.convert('L')
# Resize the image to the specified width and height
image = image.resize((width, height))
# Generate ASCII art
ascii_art = ascii_magic.from_pillow_image(image)
ascii_html = ascii_art.to_html(columns=int(columns), monochrome=True)
# Add CSS to maintain aspect ratio and improve display
html_output = f"""
{ascii_html}
"""
# Remove leading spaces from the first line
lines = ascii_html.split("\n")
if lines:
lines[0] = lines[0].lstrip()
ascii_html = "\n".join(lines)
# Save the HTML to a file
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 controls
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 display
output_html = gr.HTML(label="ASCII Art Output")
download_html = gr.File(label="Download HTML File")
# Set up event handler
convert_btn.click(
fn=convert_to_ascii,
inputs=[input_image, resolution_slider, font_slider, width_slider, height_slider],
outputs=[output_html, download_html]
)
# Also enable live updates when sliders change
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]
)
# Enable generation when image is uploaded
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)