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)