• Please review our updated Terms and Rules here

Viewing HTML on a S-100 machine with pictures.

Elinks 0.16.1 has been fantastic. (i started with the original 0.13 release from years ago)

I played around with the GEOFF Terminal as i can display bitmaps on that as well. the problem is the GEOFF terminal is barely able
to handle VT100 escape codes and thus makes it impossible to use with anything but LYNX and even then has
major issues.

I hope others try out this method it has been so much fun and opens the door to many more systems.

this can be adapted to many other terminals that can handle pixel control with escape codes.

issue will be content. the more people try this out and get excited about making HTML 1,2.0 websites then it goes back to the old days.

so much modern content is in the form of youtube channels. think about the last time you went to a personal website and not a social media site or a news site.
just the old days of finding a person with a passion for a hobby whom has a website with their interests. for me its been about 20 years.

Telnet BBS is so limited and so many of the sites barely function.

stir the pot, light the burners :)
 
Last edited:
Updated the Python Script on github.

I added 2 more display modes to the photos.

You can choose to display images as:
Bitmap 1 color with dither
Greyscale
Color with dither.

If you combine bitmap 1 color with transparency you can build an image to display very quickly.

also you can compile the python script to make it faster but you won't see much improvement at 9600 baud rates.

DSCN5997.JPG
 
new update to the script: update on github as well
Code:
# Ver 0.64 12/13/2023
# By John Galt Furball1985

# added new argument 7 which has 2 B&W picture modes and the Color mode

# you can also compile this script to make it faster
# python -m py_compile jpgtofabgl creates jpgtofabglc
# make sure to change permissions to allow it to run : chmod +x jpgtofabglc
# change to RGB to RGBA dealing with website transparency

# Fixed Cleanup and exit

# python JPGTOFABGL % A T 0 0 100 2: set Auto mode, Transparent pictures, x(not used), y(not used), width 100 pixels, color mode
# jpgtofabglc % M N 25 75 50 0: set Manual mode, solid picture, x=25, y=75, width 50 pixels, 1 bit b&w mode


from PIL import Image
import sys, termios, tty, os, time
 
def getch():
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
 
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch


# python JPGTOFABGL % A T 0 0 100

arg1 = sys.argv[1] # filename
arg2 = sys.argv[2] # Auto, Semi, Manual mode
arg3 = sys.argv[3] # T transparency 'T' or not 'N'ot a 't'
arg4 = sys.argv[4] # X
arg5 = sys.argv[5] # Y
arg6 = sys.argv[6] # resize limit
arg7 = sys.argv[7] # 0 black and white, 1 black and white 4 levels, 2 color


esc=chr(27)

FILENAME=arg1 #image can be in gif jpeg or png format

#automatic resize

image = Image.open(FILENAME)
tempimage='temp.png'

image.thumbnail((int(arg6),int(arg6)))

if arg7 == "0":
 imageout = image.convert("1",dither=Image.FLOYDSTEINBERG, palette=Image.WEB, colors=1)
 imageout.save(tempimage)
 im=Image.open(tempimage).convert('RGBA')

elif arg7 == "1":
 imageout = image.convert("L",dither=Image.FLOYDSTEINBERG, palette=Image.WEB, colors=4)
 imageout.save(tempimage)
 im=Image.open(tempimage).convert('RGBA')

else:
 imageout = image.convert("P",dither=Image.FLOYDSTEINBERG, palette=Image.WEB, colors=64)
 imageout.save(tempimage)
 im=Image.open(tempimage).convert('RGBA')

pix=im.load()
w=im.size[0]
h=im.size[1]
YY=w
XX=h

# Automatic mode one image centered screen
if arg2=="A" or arg2=="a":
 PS=512-YY
 PS2=384-XX
 PS=PS/2
 PS2=PS2/2 # The Picture in the Center of the screen X: PS2 Y: PS
 offsetx=PS
 offsety=PS2


# Semi-Automatic mode user positions possible center,left,right,middle
if arg2=="S" or arg2=="s":
 key = getch()

 if key=="L" or key=="l": #image left-top
  offsetx=128-(YY/2)
  offsety=40

 elif key=="R" or key=="r": #image right-top
  offsetx=384-(YY/2)
  offsety=40

 elif key=="M" or key=="m": #image middle-top
  offsetx=256-(YY/2)
  offsety=40

 elif key=="C" or key=="c": #image centered on screen
  PS=512-YY
  PS2=384-XX
  PS=PS/2
  PS2=PS2/2
  offsetx=PS
  offsety=PS2

 elif key=="Q" or key=="q" or key==chr(27):
  exit(0)

 else:
 # exit(0)
  PS=512-YY
  PS2=384-XX
  PS=PS/2
  PS2=PS2/2
  offsetx=PS
  offsety=PS2

# Manual Mode
if arg2=="M" or arg2=="m": # Honor user X,Y from Command prompt
 offsetx=int(arg5)
 offsety=int(arg4)

#  OUTPUT TO FABGL TERMINAL IN COLOR
if w<=500 and h<=350: # Range check to make sure we don't go nuts 500 x 350 resolution
 for i in range(w):
    for j in range(h):
     
       if arg3=="T" or arg3=="t":
        # IMAGE IS TRANSPARENT

        if pix[i,j][0]<>0 and pix[i,j][1]<>0 and pix[i,j][2]<>0:
         print(esc+"[H")
         print(esc+"_GPEN"+str(pix[i,j][0])+";"+str(pix[i,j][1])+";"+str(pix[i,j][2]))  
         print(esc+"_GPIXEL"+str(i+offsetx)+";"+str(j+offsety))

       else:
        # IMAGE IS NOT TRANSPARENT
        print(esc+"[H")
        print(esc+"_GPEN"+str(pix[i,j][0])+";"+str(pix[i,j][1])+";"+str(pix[i,j][2]))  
        print(esc+"_GPIXEL"+str(i+offsetx)+";"+str(j+offsety))
     

print (esc+"_F0;15")
print (esc+"_GPEN255;255;255")

im.close()
image.close()
sys.exit()
 
In working with elinks and talking to the author currently developing it.
I decided to add a terminal blocking mode, this will blank the screen, display the image on center then wait for a keypress after the picture is displayed before returning back to elinks control.

in elinks when you set the terminal block flag, elinks will exit to the program you set to take over but it disables the elinks HTML browser.
this is like viewing the image on its own screen. it will then pause for the user to hit enter so you can view the image then return back to elinks and
re-enable the HTML browser where you left off.

if you have terminal blocking off then it will load the image on top of the existing HTML. this can cause a few good or bad things to happen depending
on the website. elinks may also crash less as there is a race condition that occurs between 2 dialog windows. however i have crashed elinks either way.
still its another cool feature and its all controllable inside elinks.


Code:
# Ver 0.64.2 12/15/2023
# By John Galt Furball1985

# added new arguement 7 which has 2 B&W picture modes and the Color mode

# you can also compile this script to make it faster
# python -m py_compile jpgtofabgl creates jpgtofabglc
# make sure to change permissions to allow it to run : chmod +x jpgtofabglc
# change to RGB to RGBA dealing with website transparency

# Fixed Cleanup and exit

# added terminal blocking mode

# python JPGTOFABGL % A T 0 0 100 2 0: set Auto mode, Transparent pictures, x(not used), y(not used), width 100 pixels, color mode
# jpgtofabglc % M N 25 75 50 0 0: set Manual mode, solid picture, x=25, y=75, width 50 pixels, 1 bit b&w mode


from PIL import Image
import sys, termios, tty, os, time
 
def getch():
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
 
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch


# python JPGTOFABGL % A T 0 0 100

arg1 = sys.argv[1] # filename
arg2 = sys.argv[2] # Auto, Semi, Manual mode
arg3 = sys.argv[3] # T transparency 'T' or not 'N'ot a 't'
arg4 = sys.argv[4] # X
arg5 = sys.argv[5] # Y
arg6 = sys.argv[6] # resize limit
arg7 = sys.argv[7] # 0 black and white, 1 black and white 4 levels, 2 color
arg8 = sys.argv[8] # block terminal elinks yes or no 1 or 0

esc=chr(27)

FILENAME=arg1 #image can be in gif jpeg or png format

#automatic resize

image = Image.open(FILENAME)
tempimage='temp.png'

image.thumbnail((int(arg6),int(arg6)))

if arg7 == "0":
 imageout = image.convert("1",dither=Image.FLOYDSTEINBERG, palette=Image.WEB, colors=1)
 imageout.save(tempimage)
 im=Image.open(tempimage).convert('RGBA')

elif arg7 == "1":
 imageout = image.convert("L",dither=Image.FLOYDSTEINBERG, palette=Image.WEB, colors=4)
 imageout.save(tempimage)
 im=Image.open(tempimage).convert('RGBA')

else:
 imageout = image.convert("P",dither=Image.FLOYDSTEINBERG, palette=Image.WEB, colors=64)
 imageout.save(tempimage)
 im=Image.open(tempimage).convert('RGBA')

pix=im.load()
w=im.size[0]
h=im.size[1]
YY=w
XX=h

# Automatic mode one image centered screen
if arg2=="A" or arg2=="a":
 PS=512-YY
 PS2=384-XX
 PS=PS/2
 PS2=PS2/2 # The Picture in the Center of the screen X: PS2 Y: PS
 offsetx=PS
 offsety=PS2


# Semi-Automatic mode user positions possible center,left,right,middle
if arg2=="S" or arg2=="s":
 key = getch()

 if key=="L" or key=="l": #image left-top
  offsetx=128-(YY/2)
  offsety=40

 elif key=="R" or key=="r": #image right-top
  offsetx=384-(YY/2)
  offsety=40

 elif key=="M" or key=="m": #image middle-top
  offsetx=256-(YY/2)
  offsety=40

 elif key=="C" or key=="c": #image centered on screen
  PS=512-YY
  PS2=384-XX
  PS=PS/2
  PS2=PS2/2
  offsetx=PS
  offsety=PS2

 elif key=="Q" or key=="q" or key==chr(27):
  im.close()
  image.close()
  sys.exit()
 
 else: #just exit out if you push wrong button
  im.close()
  image.close()
  sys.exit()
  # PS=512-YY
  # PS2=384-XX
  # PS=PS/2
  # PS2=PS2/2
  # offsetx=PS
  # offsety=PS2

# Manual Mode
if arg2=="M" or arg2=="m": # Honor user X,Y from Command prompt
 offsetx=int(arg5)
 offsety=int(arg4)

if arg8 == "1": # we are blocking terminal so clear screen
 print (esc+"[2J")

#  OUTPUT TO FABGL TERMINAL IN COLOR
if w<=500 and h<=350: # Range check to make sure we don't go nuts 500 x 350 resolution
 for i in range(w):
    for j in range(h):
    
       if arg3=="T" or arg3=="t":
        # IMAGE IS TRANSPARENT

        if pix[i,j][0]<>0 and pix[i,j][1]<>0 and pix[i,j][2]<>0:
         print(esc+"[H")
         print(esc+"_GPEN"+str(pix[i,j][0])+";"+str(pix[i,j][1])+";"+str(pix[i,j][2])) 
         print(esc+"_GPIXEL"+str(i+offsetx)+";"+str(j+offsety))

       else:
        # IMAGE IS NOT TRANSPARENT
        print(esc+"[H")
        print(esc+"_GPEN"+str(pix[i,j][0])+";"+str(pix[i,j][1])+";"+str(pix[i,j][2])) 
        print(esc+"_GPIXEL"+str(i+offsetx)+";"+str(j+offsety))
    

print (esc+"_F0;15")
print (esc+"_GPEN255;255;255")

if arg8 == "1": # halt for keypress here and i need LINES and COLUMNS
 LINES1=int(os.environ["LINES"])
 COLUMNS1=int(os.environ["COLUMNS"])
 LINES1=LINES1-1
 COLUMNS1=(COLUMNS1/2)-11
 raw_input(esc+"["+str(LINES1)+";"+str(COLUMNS1)+"fPress Enter to Return.")

im.close()
image.close()
sys.exit()
 
I have been working in Python 2 and that proved to be very problematic.

python 2 has a real issue with keyboard input I tried to work around it but as the program has become complex it has proven to be fruitless and frustrating.

starting from here i have switched to python 3.

the getchr() function has been replaced with a native function in python 3

this removed bugs with the semi automatic mode.

Python 3 uses some slightly different naming so i had to change some of the logic symbols as well.

you can of course run this program outside of elinks from the command prompt and it will display most types of graphic photos to the FABGL terminal and it can be customized in the same way for a full screen or a fast preview.

Code:
# Ver 0.64.3 12/16/2023
# By John Galt Furball1985

# Change to Python 3

# added new argument 7 which has 2 B&W picture modes and the Color mode

# you can also compile this script to make it faster
# python3 -m py_compile jpgtofabgl creates jpgtofabglc
# make sure to change permissions to allow it to run : chmod +x jpgtofabglc
# change to RGB to RGBA dealing with website transparency

# Fixed Cleanup and exit

# added terminal blocking mode

# python JPGTOFABGL %f A T 0 0 100 2 0: set Auto mode, Transparent pictures, x(not used), y(not used), width 100 pixels, color mode
# jpgtofabglc %f M N 25 75 50 0 0: set Manual mode, solid picture, x=25, y=75, width 50 pixels, 1 bit b&w mode


from PIL import Image
import sys, termios, tty, os, time, getch
 
# python JPGTOFABGL %f A T 0 0 100 2 0

arg1 = sys.argv[1] # filename
arg2 = sys.argv[2] # Auto, Semi, Manual mode
arg3 = sys.argv[3] # T transparency 'T' or not 'N'ot a 't'
arg4 = sys.argv[4] # X
arg5 = sys.argv[5] # Y
arg6 = sys.argv[6] # resize limit
arg7 = sys.argv[7] # 0 black and white, 1 black and white 4 levels, 2 color
arg8 = sys.argv[8] # block terminal elinks yes or no 1 or 0

esc=chr(27)

if arg8 == "1": # we are blocking terminal so clear screen
 print (esc+"[2J")

FILENAME=arg1 #image can be in gif jpeg or png format

#automatic resize

image = Image.open(FILENAME)
tempimage='temp.png'

image.thumbnail((int(arg6),int(arg6)))

if arg7 == "0":
 imageout = image.convert("1",dither=Image.FLOYDSTEINBERG, palette=Image.WEB, colors=1)
 imageout.save(tempimage)
 im=Image.open(tempimage).convert('RGBA')

elif arg7 == "1":
 imageout = image.convert("L",dither=Image.FLOYDSTEINBERG, palette=Image.WEB, colors=4)
 imageout.save(tempimage)
 im=Image.open(tempimage).convert('RGBA')

else:
 imageout = image.convert("P",dither=Image.FLOYDSTEINBERG, palette=Image.WEB, colors=64)
 imageout.save(tempimage)
 im=Image.open(tempimage).convert('RGBA')

pix=im.load()
w=im.size[0]
h=im.size[1]
YY=w
XX=h

# Automatic mode one image centered screen
if arg2=="A" or arg2=="a":
 PS=512-YY
 PS2=384-XX
 PS=PS/2
 PS2=PS2/2 # The Picture in the Center of the screen X: PS2 Y: PS
 offsetx=PS
 offsety=PS2


# Semi-Automatic mode user positions possible center,left,right,middle
if arg2=="S" or arg2=="s":
 key = getch()

 if key=="L" or key=="l": #image left-top
  offsetx=128-(YY/2)
  offsety=40

 elif key=="R" or key=="r": #image right-top
  offsetx=384-(YY/2)
  offsety=40

 elif key=="M" or key=="m": #image middle-top
  offsetx=256-(YY/2)
  offsety=40

 elif key=="C" or key=="c": #image centered on screen
  PS=512-YY
  PS2=384-XX
  PS=PS/2
  PS2=PS2/2
  offsetx=PS
  offsety=PS2

 elif key=="Q" or key=="q" or key==chr(27):
  im.close()
  image.close()
  sys.exit()
 
 else: #just exit out if you push wrong button
  im.close()
  image.close()
  sys.exit()
  # PS=512-YY
  # PS2=384-XX
  # PS=PS/2
  # PS2=PS2/2
  # offsetx=PS
  # offsety=PS2

# Manual Mode
if arg2=="M" or arg2=="m": # Honor user X,Y from Command prompt
 offsetx=int(arg5)
 offsety=int(arg4)

#if arg8 == "1": # we are blocking terminal so clear screen
# print (esc+"[2J")

#  OUTPUT TO FABGL TERMINAL IN COLOR
if w<=500 and h<=350: # Range check to make sure we don't go nuts 500 x 350 resolution
 for i in range(w):
    for j in range(h):
      
       if arg3=="T" or arg3=="t":
        # IMAGE IS TRANSPARENT

        if pix[i,j][0]!=0 and pix[i,j][1]!=0 and pix[i,j][2]!=0:
         print(esc+"[H")
         print(esc+"_GPEN"+str(pix[i,j][0])+";"+str(pix[i,j][1])+";"+str(pix[i,j][2]))   
         print(esc+"_GPIXEL"+str(i+offsetx)+";"+str(j+offsety))

       else:
        # IMAGE IS NOT TRANSPARENT
        print(esc+"[H")
        print(esc+"_GPEN"+str(pix[i,j][0])+";"+str(pix[i,j][1])+";"+str(pix[i,j][2]))   
        print(esc+"_GPIXEL"+str(i+offsetx)+";"+str(j+offsety))
      

print (esc+"_F0;15")
print (esc+"_GPEN255;255;255")

if arg8 == "1": # halt for keypress here and i need LINES and COLUMNS
 LINES1=int(os.environ["LINES"])
 COLUMNS1=int(os.environ["COLUMNS"])
 LINES1=LINES1-1
 COLUMNS1=(COLUMNS1/2)-11
 raw_input(esc+"["+str(LINES1)+";"+str(COLUMNS1)+"fPress Enter to Return.")

im.close()
image.close()
sys.exit()
 
Back
Top