// This program takes an image and turns it into something that could display // on a TRS-80 Model I,III,or 4. 128x48, black and white, baby. // // If passed an argument on the command-line, it will display the specified // file or URL. // You'll need the background image available at: // // https://futureboy.us/frinksamp/trs80iiib.jpg // bg = new image["file:trs80iiib.jpg"] if (length[ARGS] > 0) if (ARGS@0 =~ %r/^http/) i = new image[ARGS@0] else i = new image["file:" + ARGS@0] else i = new image["https://futureboy.us/images/futureboydomethumb4.gif"] w = i.getWidth[] h = i.getHeight[] pw = 128 ph = 48 xstep = w/pw ystep = h/ph ni = new image[pw,ph] // Create a grayscale version of the image. xx = 0 for x=0 to w-xstep step xstep { yy = 0 for y = 0 to h-ystep step ystep { [r,g,b,a] = i.averagePixels[x,y,x+xstep, y+ystep] gray = (r+g+b)/3 ni.setPixel[xx,yy,gray,gray,gray,a] yy = yy + 1 } xx = xx + 1 } rerror = 0 gerror = 0 berror = 0 gr = new graphics gr.draw[bg, -75, -65, 364, 275] gr.backgroundColor[0,0,0] // Floyd-Steinberg dither. for x = 0 to pw-1 for y = 0 to ph-1 { [r,g,b,a] = ni.getPixel[x,y] gray = (r+g+b) / 3 if gray > 1/2 { c = 1 gr.color[1,1,1,.7] gr.fillRectCenter[x,y*2,1,2] } else c = 0 ni.setPixel[x,y,c,c,c,a] err = gray - c addError[ni, x+1, y, 7/16, err] addError[ni, x-1, y+1, 3/16, err] addError[ni, x, y+1, 5/16, err] addError[ni, x+1, y+1, 1/16, err] } gr.show[] // Adds the error term to an existing pixel. addError[image, x, y, mult, err] := { if (x<0) || (y<0) || (x>=image.getWidth[]) || (y>=image.getHeight[]) return [r,g,b,a] = image.getPixel[x,y] r = clamp[r+mult*err] g = clamp[g+mult*err] b = clamp[b+mult*err] image.setPixel[x,y,r,g,b,a] } clamp[v, min=0, max=1] := { if v < min min else if v > max max else v }