Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from PIL import Image | |
| import numpy as np | |
| def image_to_ascii(image, width=100, chars="@%#*+=-:. "): | |
| """ | |
| Convert image to ASCII art | |
| """ | |
| # Convert image to grayscale | |
| if image.mode != 'L': | |
| image = image.convert('L') | |
| # Resize image while maintaining aspect ratio | |
| original_width, original_height = image.size | |
| aspect_ratio = original_height / original_width | |
| height = int(width * aspect_ratio * 0.55) # 0.55 to account for character aspect ratio | |
| # Resize image | |
| img_resized = image.resize((width, height)) | |
| # Convert to numpy array | |
| pixels = np.array(img_resized) | |
| # Normalize pixels to 0-1 range | |
| pixels = pixels / 255.0 | |
| # Map pixels to ASCII characters | |
| ascii_chars = list(chars) | |
| num_chars = len(ascii_chars) | |
| # Create ASCII art | |
| ascii_art = [] | |
| for row in pixels: | |
| line = ''.join(ascii_chars[min(int(pixel * num_chars), num_chars - 1)] for pixel in row) | |
| ascii_art.append(line) | |
| return '\n'.join(ascii_art) | |
| def process_image(image, width, character_set): | |
| """ | |
| Process the uploaded image and convert to ASCII art | |
| """ | |
| if image is None: | |
| return "Please upload an image first!" | |
| try: | |
| # Define character sets | |
| char_sets = { | |
| "Detailed (dense)": "@%#*+=-:. ", | |
| "Simple (sparse)": "@#*+-. ", | |
| "Blocks": "█▓▒░ ", | |
| "Inverted": " .:-=+*#%@", | |
| "Custom": character_set | |
| } | |
| chars = char_sets.get(character_set, "@%#*+=-:. ") | |
| ascii_result = image_to_ascii(image, width, chars) | |
| return f"```\n{ascii_result}\n```" | |
| except Exception as e: | |
| return f"Error processing image: {str(e)}" | |
| # Create Gradio interface | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# Image to ASCII Art Converter") | |
| gr.Markdown("Convert your images to ASCII art! Upload an image, adjust the width and character set, and see the text-based version of your image.") | |
| with gr.Row(): | |
| with gr.Column(): | |
| image_input = gr.Image(type="pil", label="Upload Image") | |
| width_slider = gr.Slider(minimum=50, maximum=200, value=100, step=10, label="ASCII Art Width") | |
| char_set_dropdown = gr.Dropdown( | |
| choices=["Detailed (dense)", "Simple (sparse)", "Blocks", "Inverted", "Custom"], | |
| value="Detailed (dense)", | |
| label="Character Set" | |
| ) | |
| custom_chars = gr.Textbox( | |
| value="@%#*+=-:. ", | |
| label="Custom Character Set (used when 'Custom' is selected)", | |
| placeholder="Enter characters from darkest to lightest" | |
| ) | |
| submit_btn = gr.Button("Convert to ASCII") | |
| with gr.Column(): | |
| output_text = gr.Textbox( | |
| label="ASCII Art Result", | |
| lines=20, | |
| max_lines=50, | |
| show_copy_button=True | |
| ) | |
| # Update character set based on dropdown selection | |
| def update_char_set(character_set, custom_chars): | |
| char_sets = { | |
| "Detailed (dense)": "@%#*+=-:. ", | |
| "Simple (sparse)": "@#*+-. ", | |
| "Blocks": "█▓▒░ ", | |
| "Inverted": " .:-=+*#%@", | |
| "Custom": custom_chars | |
| } | |
| return char_sets.get(character_set, "@%#*+=-:. ") | |
| # Process function that uses the selected character set | |
| def process_with_char_set(image, width, character_set, custom_chars): | |
| char_sets = { | |
| "Detailed (dense)": "@%#*+=-:. ", | |
| "Simple (sparse)": "@#*+-. ", | |
| "Blocks": "█▓▒░ ", | |
| "Inverted": " .:-=+*#%@", | |
| "Custom": custom_chars | |
| } | |
| chars = char_sets.get(character_set, "@%#*+=-:. ") | |
| if image is None: | |
| return "Please upload an image first!" | |
| try: | |
| ascii_result = image_to_ascii(image, width, chars) | |
| return f"\n{ascii_result}\n" | |
| except Exception as e: | |
| return f"Error processing image: {str(e)}" | |
| # Connect the components | |
| char_set_dropdown.change( | |
| update_char_set, | |
| inputs=[char_set_dropdown, custom_chars], | |
| outputs=custom_chars | |
| ) | |
| submit_btn.click( | |
| process_with_char_set, | |
| inputs=[image_input, width_slider, char_set_dropdown, custom_chars], | |
| outputs=[output_text] | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |