ASCII Art

Definitions

ASCII (American Standard Code for Information Interchange)

  • 7 bit character encoding
  • Code 32 - 127 are printable characters
  • Originally developed for use with teletypes
  • Extended version with 8 bits also exists

Unicode (The Unicode Standard)

  • Text encoding standard
  • Capable of encoding more than 1.1 million characters
  • Unicode has many encoding types, (UTF-8, UTF-16)
  • UTF-8 backwards compatible with ASCII
  • Includes Japanese characters, emojis etc

Shell

  • Program that allows you to interact with the OS usually through CLI
  • Bash, Zsh for example

Terminal

  • The program where you type to execute commands
  • Used to be a physical device with a keyboard
  • Now commonly also known as teminal emulators
  • The terminal is the environment which allows you to interact with the shell
  • Modern terminals typically utilise Unicode
  • Gnome Terminal for example

ANSI Escape Code

  • Sequence of characters used to control the properties of text in a terminal
  • Change text colour, background colour, text attributes etc
# Print Hello World in red in the terminal
printf "\033[31mHello World\033[m\n"

Demo

Image to ASCII

  • Possible to convert image to ASCII based on intensity
  • Greyscale/intensity to ASCII ramp

$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,”^`’.

  • ASCII characters on the left have larger density to appear more intense
  • This depends on the typeset
  • Width and height of character cell is usually not 1:1
  • Need to double width to get a somewhat reasonable aspect ratio
  • Below ASCII art was generated with the script in the Appendix
  • Had to manually convert the coloured Tux using ansi2html command to display them nicely on the web

ASCII of Tux

@@@@@@@@ @@@@@@@@hX*@ @@@@@@@@B@@@@ @@@@W@@@j[%@@@@ @x@w @@ @h @@@@ @@8@?+(>@@ @@@@ @\}?+i><<[@@@@ @v}?+<u((t@Bnh@ @@i-uYz}+:..@@@@@ @@ ^i>,. @@@@@ @@@ . ^'@@@@@@ @@@L: ^ .:>!`@dB@@@ @h@. ^.%h*B@@ M@] ' @@@O@@@ @B@ ^ @@0@@@ @&ou ^ @@M@@@$ |}8_ ^ YaB%aU@ |?-?)@m ' r]}@@@@B-{ 1???-----[@@@ `>x]}tLX(?_] )---------?@@@ 'iu[-?[]-___-{ (?---------]n @@u[________-]| r}?----------}z@v J@@@@@x]___-?{/xcM purf/(1[?--](z@@@@@@@@@@@MY/)1(tvC CzucQa bmQLQZ

ASCII of Tux with ANSI colour

@@@@@@@@ @@@@@@@@hX*@ @@@@@@@@B@@@@ @@@@W@@@j[%@@@@ @x@w @@ @h @@@@ @@8@?+(>@@ @@@@ @\}?+i><<[@@@@ @v}?+<u((t@Bnh@ @@i-uYz}+:..@@@@@ @@ ^i>,. @@@@@ @@@ . ^'@@@@@@ @@@L: ^ .:>!`@dB@@@ @h@. ^.%h*B@@ M@] ' @@@O@@@ @B@ ^ @@0@@@ @&ou ^ @@M@@@$ |}8_ ^ YaB%aU@ |?-?)@m ' r]}@@@@B-{ 1???-----[@@@ `>x]}tLX(?_] )---------?@@@ 'iu[-?[]-___-{ (?---------]n @@u[________-]| r}?----------}z@v J@@@@@x]___-?{/xcM purf/(1[?--](z@@@@@@@@@@@MY/)1(tvC CzucQa bmQLQZ

ASCII of Tux with ANSI background colour

Appendix

# Print out art to your terminal
import math
from enum import Enum
import cv2
import numpy as np

ASCII_RAMP = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
RAMP_LEN = len(ASCII_RAMP)

class Render(Enum):
    ASCII          = 1
    RGB_ASCII      = 2
    RGB_BACKGROUND = 3

# Changes text colour
def ansi_rgb(r, g, b, c):
    return "\x1b[38;2;"+str(r)+";"+str(g)+";"+str(b)+"m"+c+"\x1b[0m"

# Changes background colour
def ansi_rgb_bg(r, g, b):
    return "\x1b[48;2;"+str(r)+";"+str(g)+";"+str(b)+"m \x1b[0m"

img = cv2.imread("tux.png", cv2.IMREAD_UNCHANGED)
img = cv2.resize(img, (0,0), fx=0.1, fy=0.05)

height, width, depth = img.shape

art = ""

render = Render.RGB_ASCII

for i in range(height):
    for j in range(width):
        r = img[i,j,2]
        g = img[i,j,1]
        b = img[i,j,0]
        a = img[i,j,3] if depth == 4 else 255
        if a == 0:
            r = g = b = 255
        grey = 0.299 * r + 0.587 * g + 0.114 * b 
        c = ASCII_RAMP[math.ceil((RAMP_LEN - 1) * grey / 255)] 
        if render == Render.ASCII:
            art += c
        elif render == Render.RGB_ASCII:
            art += ansi_rgb(r, g, b, c)
        elif render == Render.RGB_BACKGROUND:
            art += ansi_rgb_bg(r, g, b)

    art += "\n"

print(art)
Written on August 3, 2024