Skip to content

Instantly share code, notes, and snippets.

@technige
Created January 13, 2023 00:55
Show Gist options
  • Save technige/7da9d7dbed25c3f41c78201bad4d5f9e to your computer and use it in GitHub Desktop.
Save technige/7da9d7dbed25c3f41c78201bad4d5f9e to your computer and use it in GitHub Desktop.
from argparse import ArgumentParser
from io import BytesIO
from PIL.Image import open as open_image
def image_to_ansi(data, scale=1):
# TODO: optimise this algorithm - it's pretty brute-force right now
image = open_image(BytesIO(data))
width, height = image.size
ansi_width = int(scale * width // 8) # assume font is 8 pixels wide
ansi_height = int(scale * height // 8) # assume font is 8×2 pixels high
ansi_image = image.resize((ansi_width, ansi_height))
pixels = list(ansi_image.getdata())
lines = []
p0 = 0
while p0 < len(pixels):
p1 = p0 + ansi_width
p2 = p1 + ansi_width
line0 = pixels[p0:p1]
line1 = pixels[p1:p2]
p0 = p2
line = []
for i, rgb0 in enumerate(line0):
try:
rgb1 = line1[i]
except IndexError:
rgb1 = [(0, 0, 0) for _ in range(len(rgb0))]
line.append(f"\x1b[38;2;{rgb0[0]};{rgb0[1]};{rgb0[2]}m") # Select RGB foreground color
if rgb0 == rgb1:
line.append("\u2588") # U+2588 █ FULL BLOCK
else:
line.append(f"\x1b[48;2;{rgb1[0]};{rgb1[1]};{rgb1[2]}m") # Select RGB background color
line.append("\u2580") # U+2580 ▀ UPPER HALF BLOCK
line.append("\x1b[0m")
lines.append("".join(line))
return "\n".join(lines)
def main():
parser = ArgumentParser()
parser.add_argument("filename")
parser.add_argument("-x", "--scale", type=float, default=1)
parsed = parser.parse_args()
with open(parsed.filename, "rb") as f:
print(image_to_ansi(f.read(), scale=parsed.scale))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment