FloydSteinbergDither.frink

View or download FloydSteinbergDither.frink in plain text format


// Floyd-Steinberg dithering test

// 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.

//i = new image["http://futureboy.us/images/futureboydomethumb4.gif"]
//i=new image["http://www.foxnews.com/images/302417/0_61_mckellar_danica.jpg"]
//i=new image["http://www.gossipboulevard.com/wp-content/uploads/2009/02/danica-mckellar2.jpg"]
//i=new image["http://www.gossipboulevard.com/wp-content/uploads/2009/02/danica-mckellar1-150x150.jpg"]

if (length[ARGS] > 0)
   i = new image["file:" + ARGS@0]
else
   i=new image["http://futureboy.us/images/futureboydomethumb4.gif"]

i.show[]

i.show[]
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.backgroundColor[0,0,0]

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
      else
         c = 0
      err = gray - c
      ni.setPixel[x,y,c,c,c,a]
      gr.color[c,c,c,a]
      gr.fillRectCenter[x,y*2,1,2]
      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]
   }

   
ni.show[]
gr.show[]
   
//      println["$r $g $b $a"]
//      gr.color[c,c,c,a]
//      gr.fillRectCenter[x,y,xstep,ystep]
//      gr.fillEllipseCenter[x,y,xstep,ystep]
//      gr.text["\u03c0",x,y]


//i.show[]
//gr.show[]

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
}


View or download FloydSteinbergDither.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 17591 days, 17 hours, 37 minutes ago.