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 17646 days, 9 hours, 40 minutes ago.