Text Graphics

While I was working on curses text based graphical interfaces I came across two interesting Linux text applications:

  • cowsay – generates ASCII pictures of a cow (or other animals) with a message
  • jp2a – a small utility that converts JPG images to ASCII.

I this blog I wanted to document some of the things that I found and how these utilities could be used in a ncurses program.

Cowsay

Cowsay has been around in the Linux world since 2007. It is now available in Windows and Android. To install cowsay in Linux or a Rasberry Pi :

sudo apt-get install cowsay

Coway takes text messages that you pass it.

~$ cowsay "I'm not worried about mad cow...because I'm a helicopter"
 _________________________________________
/ I'm not worried about mad cow...because \
\ I'm a helicopter                       /
 -----------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

If you install the Linux fortune app (sudo apt install fortune) you can pass random fortune messages:

~$ fortune | cowsay
 _______________________________________
/ You get along very well with everyone \
\ except animals and people.            /
 ---------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

There are a number of different images that can be used. To see the list of what is available:

~$ cowsay -l
Cow files in /usr/share/cowsay/cows:
apt bud-frogs bunny calvin cheese cock cower daemon default dragon
dragon-and-cow duck elephant elephant-in-snake eyes flaming-sheep
ghostbusters gnu hellokitty kiss koala kosh luke-koala mech-and-cow milk
moofasa moose pony pony-smaller ren sheep skeleton snowman stegosaurus
stimpy suse three-eyes turkey turtle tux unipony unipony-smaller vader
vader-koala www

To display all the images:

~$ for i in $(cowsay -l); do cowsay -f $i "$i"; done
 _____
< apt >
 -----
       \ (__)
         (oo)
   /------\/
  / |    ||
 *  /\---/\
    ~~   ~~
 ___________
< bud-frogs >
 -----------
     \
      \
          oO)-.                       .-(Oo
         /__  _\                     /_  __\
         \  \(  |     ()~()         |  )/  /
          \__|\ |    (-___-)        | /|__/
          '  '--'    ==`-'==        '--'  '
 _______
< bunny >
 -------
  \
   \   \
        \ /\
        ( )
      .( o ).

....and a bunch more

 Cowsay in Python

There is a native Python cowsay library:

~$ pip install cowsay --user

An example from the Python command line:

>>> import cowsay
>>> cowsay.cow("This is from Python")
  ___________________
< This is from Python >
  ===================
                        \
                         \
                           ^__^                             
                           (oo)\_______                   
                           (__)\       )\/\             
                               ||----w |           
                               ||     ||  

Cowsay in a Curses App

As an example I wanted to make a Raspberry Pi intrusion monitor. First I created a cowsay images with some eyes:

~$ cowsay -f eyes "Raspberry Pi - Intrusion Monitor"

eyes

Once I was happy with the presentation I saved the output to a file:

~$ cowsay -f eyes “Raspberry Pi – Intrusion Monitor” > eyes.txt

In my Python curses app I read the eyes.txt file and used the stdscr.addstr method to write it to the screen. (Note: For more info on writing Python/C curses or Lua curses)


# c_eyes.py - create a curses with a cowsay message
#
import curses , time, random

# create a curses object
stdscr = curses.initscr()
height, width = stdscr.getmaxyx() # get the window size

# define two color pairs
curses.start_color()
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_WHITE)
curses.init_pair(2, curses.COLOR_YELLOW, curses.COLOR_BLACK)
curses.init_pair(3, curses.COLOR_BLUE, curses.COLOR_BLACK)

# Read the cowsay output file and write it to the screen

f = open("eyes.txt", "r")
eyes = f.read()
stdscr.addstr(0, 0, eyes,curses.color_pair(3))

# Add a footer
stdscr.addstr(height-1, 0, " " * (width-1),curses.color_pair(1))
stdscr.addstr(height-1, 0, " Key Commands : q - to quit " ,curses.color_pair(1))

# Add intrusion code here....
stdscr.addstr(15, 5, "PIR1 input: no movement" ,curses.color_pair(2) )
stdscr.addstr(16, 5, "PIR2 input: no movement" ,curses.color_pair(2) )

curses.curs_set(0) # don't show the cursor
stdscr.refresh()

# Cycle to update text. Enter a 'q' to quit
k = 0
stdscr.nodelay(1)
while (k != ord('q')):
    k = stdscr.getch()

curses.endwin()

c_eyes

jp2a –¬† converts JPG images to ASCII

jp2a is a Linux utility that is installed by:

apt-get install jp2a

I found that you’ve got to be selective of the jpeg image that you are trying to convert an example of a castle:

 jp2a castle.jpg --colors --background=light 

Another example was to convert a flag. For this example I found the width option to be useful:

 jp2a can.jpg --colors --width=70