67 lines
1.9 KiB
Python
67 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Quick ASCII art generator from image URLs.
|
|
|
|
Usage: python ascii_image_generator.py <image_url> [output_width]
|
|
|
|
Produces ASCII art of the image.
|
|
"""
|
|
|
|
import sys
|
|
import io
|
|
import urllib.request
|
|
from PIL import Image
|
|
|
|
ASCII_CHARS = "@%#*+=-:. "
|
|
ASCII_CHARS_REVERSE = " " + ":-.=+*#%%@"
|
|
|
|
def download_image(url: str) -> Image.Image:
|
|
"""Download image from URL."""
|
|
with urllib.request.urlopen(url, timeout=30) as response:
|
|
data = response.read()
|
|
return Image.open(io.BytesIO(data))
|
|
|
|
def resize_image(img: Image.Image, new_width: int = 80) -> Image.Image:
|
|
"""Resize image maintaining aspect ratio."""
|
|
w, h = img.size
|
|
aspect_ratio = h / w
|
|
new_height = int(aspect_ratio * new_width * 0.55) # 0.55 accounts for char height
|
|
return img.resize((new_width, max(1, new_height)))
|
|
|
|
def image_to_ascii(img: Image.Image, width: int = 80) -> str:
|
|
"""Convert PIL Image to ASCII art string."""
|
|
img = resize_image(img, width)
|
|
img = img.convert("L") # Grayscale
|
|
pixels = list(img.getdata())
|
|
chars_per_pixel = len(ASCII_CHARS)
|
|
|
|
ascii_str = ""
|
|
for i, pixel in enumerate(pixels):
|
|
if i > 0 and (i % width) == 0:
|
|
ascii_str += "\n"
|
|
idx = min(pixel * (chars_per_pixel - 1) // 255, chars_per_pixel - 1)
|
|
ascii_str += ASCII_CHARS[idx]
|
|
return ascii_str
|
|
|
|
def main():
|
|
if len(sys.argv) < 2:
|
|
print(__doc__)
|
|
sys.exit(1)
|
|
|
|
url = sys.argv[1]
|
|
width = int(sys.argv[2]) if len(sys.argv) > 2 else 80
|
|
|
|
print(f"Downloading from {url}...")
|
|
img = download_image(url)
|
|
print(f"Image size: {img.size}, converting to ASCII (width={width})...")
|
|
|
|
ascii_art = image_to_ascii(img, width)
|
|
print(ascii_art)
|
|
|
|
# Save to file
|
|
output_path = "/root/.hermes/wizard-outputs/spark/output_ascii.txt"
|
|
with open(output_path, "w") as f:
|
|
f.write(ascii_art)
|
|
print(f"\nSaved to {output_path}")
|
|
|
|
if __name__ == "__main__":
|
|
main() |