qrcodeembroider.frink

Download or view qrcodeembroider.frink in plain text format


// Program to simulate cross-stitch.

// Draws a single "x" in a cross-stitch.
drawX[gr is graphics, left, top, right, bottom, r, g, b, sdColor, threadWidth, subThreads, jitter] :=
{
   width = right-left
   height = bottom-top
   halfWidth = width / 2
   halfHeight = height / 2

   perSide = sqrt[subThreads]

   // Width of each sub-thread
   subWidth = threadWidth / perSide * 1.1   // TODO:  Make this changeable
   halfThreadWidth = threadWidth / 2
   quarterThreadWidth = threadWidth / 4

   xc1 = left  + halfThreadWidth
   yc1 = top  + halfThreadWidth
   
   xc2 = right - halfThreadWidth
   yc2 = bottom  - halfThreadWidth

   halfThreadWidth = threadWidth / 2
   
   gr.stroke[subWidth]
   gr.color[.5,.5,.5]
   gr.fillEllipseCenter[right,bottom,threadWidth,threadWidth]
   for n = 0 to subThreads-1
   {
      xx = (n mod perSide) / perSide
      yy = (n div perSide) / perSide

      xo = threadWidth * xx - halfThreadWidth
      yo = threadWidth * yy - halfThreadWidth

      jitterWidth = subWidth * jitter
      
      gr.color[randColor[r, sdColor],
               randColor[g, sdColor],
               randColor[b, sdColor],
               .5]

      gr.line[randomGaussian[xc1 + xo, jitterWidth],
              randomGaussian[yc1 + yo, jitterWidth],
              randomGaussian[xc2 + xo, jitterWidth],
              randomGaussian[yc2 + yo, jitterWidth]]

      gr.color[randColor[r, sdColor],
               randColor[g, sdColor],
               randColor[b, sdColor],
               .5]
      
      gr.line[randomGaussian[xc1 + xo, jitterWidth],
              randomGaussian[yc2 + yo, jitterWidth],
              randomGaussian[xc2 + xo, jitterWidth],
              randomGaussian[yc1 + yo, jitterWidth]]
   }
}

// Picks a normally-distributed color component around the color component x
// with specified standard deviation.
randColor[x, sd] := constrain[randomGaussian[x, sd], 0, 1]

// Constrains the value of x to be between min and max.
constrain[x, min, max] := (x < min ? min : (x > max ? max : x))

// Draw a cross-stitch of the image.
crossStitchImage[gr is graphics, i, left, top, right, bottom, steps] :=
{
   w = i.getWidth[]
   h = i.getHeight[]

   aspect = w/h
   if (aspect > 1)              // Wider than tall?
   {
      xstep = w/round[steps*aspect]
      ystep = h/steps
   } else
   {
      xstep = w / steps
      ystep = h / round[steps/aspect]
   }

   threadWidth = .3 xstep
   
   for x=0 to w-xstep step xstep
      for y = 0 to h-ystep step ystep
      {
         [r,g,b,a] = i.averagePixels[x,y,x+xstep, y+ystep]
         drawX[gr,x,y,x+xstep,y+ystep,r,g,b,.15,threadWidth,36,.7]
      }
}

g = new graphics
g.backgroundColor[0.7,0.7,0.7]
//i = new image["http://futureboy.us/images/futureboydomethumb4.gif"]
//i = new image["file:maui.jpg"]
//i = new image["file:kittyface.jpg"]
i = qrcode["https://triplenine.org","L"]

crossStitchImage[g, i, 0, 0, 1, 1, 33]
g.show[]
g.write["qrcodeembroider.html",1000,1000]
browse["qrcodeembroider.html"]
g.write["qrcodeembroider.svg",1000,1000]
g.write["qrcodeembroider.png",1000,undef]

// Generates a QRcode image using Google Charts API:
// http://code.google.com/apis/chart/docs/gallery/qr_codes.html

// Generate a QRcode image and return that image.
// errorCorrection is a letter consisting of one of the following:
// "L" (can correct up to  7% errors)
// "M" (can correct up to 15% errors)
// "Q" (can correct up to 25% errors)
// "H" (can correct up to 30% errors)
qrcode[text, errorCorrection="M", width=400, height=400] :=
{
   return new image["http://chart.apis.google.com/chart?cht=qr&chs=${width}x${height}&chld=$errorCorrection&chl=" + URLEncode[text, "UTF8"]]
}


Download or view qrcodeembroider.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 20217 days, 23 hours, 41 minutes ago.