Skip to content

A command-line tool for generating unique images.

License

Notifications You must be signed in to change notification settings

ajagnic/gogenart

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

70 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Generative Art in Go

My take on the work presented in preslavrachev/generative-art-in-go. This project differs from Preslav's by a couple of things:

  • gogenart is firstly structured as a command line tool, although the sketch package can be imported
  • The drawing algorithm implements pixel luminance as a scaling factor. This essentially uses the origin image as a 'heatmap' of sorts, in which larger polygons will be drawn where pixels are brighter

Libraries

Usage

Usage of ./gogenart:
  -color uint
        percent chance to randomize polygon color
  -fill uint
        percent chance to fill polygon (default 100)
  -grey
        convert to greyscale
  -height uint
        desired height of image
  -i int
        number of iterations (default 10000)
  -invert
        invert luminance scaling
  -max uint
        maximum number of polygon sides (default 5)
  -min uint
        minimum number of polygon sides (default 3)
  -o string
        file to use as output
  -s float
        polygon size (percentage of width) (default 0.1)
  -shake float
        amount to randomize pixel positions
  -spin uint
        max degrees to rotate pixel positions
  -width uint
        desired width of image
# All of the following are equivalent:
$ cat example.jpeg | gogenart > result.jpeg

$ gogenart example.jpeg > result.jpeg

$ gogenart -o=result.jpeg example.jpeg
# Both JPEG and PNG files can be used.
$ gogenart example.png > result.png

# Format can be converted if using the -o flag.
$ gogenart -o=result.png example.jpeg

The Drawing Algorithm

// A random pixel is selected,
// its luminance is used to scale a polygon,
// and the polygon is drawn with the color of that pixel.
rx := rand.Float64() * s.width
ry := rand.Float64() * s.height
...
l := luminance(r, g, b)
stroke := s.stroke * l
...
s.dc.SetRGBA255(r, g, b, rand.Intn(256))
s.dc.DrawRegularPolygon(sides, x, y, stroke, rand.Float64())
...

Examples

Depending on the parameters used and their values, one can achieve a wide range of effects.

Here we keep most of the resolution of the original image, due to the high iteration and small polygon size.

$ ./gogenart -i=250000 -s=0.03 -fill=10 -shake=0.01 -grey \
-o=examples/crane.jpeg \
examples/crane-original.jpg

With low iteration and large polygons, a lot of shake, and completely random color, we can create an entirely original image.

$ ./gogenart -i=2000 -s=0.2 -min=2 -max=3 -shake=0.2 -fill=50 -color=100 \
-o=examples/rose.jpeg \
examples/rose-original.jpg

Using the sketch package

f, _ := os.Open("example.jpeg")

img, enc := sketch.Source(f) // decode image from io.Reader

config := sketch.Params{
      Iterations:         10000,
      PolygonSidesMin:    3,
      PolygonSidesMax:    5,
      PolygonFillChance:  1.0,
      PolygonColorChance: 0.0,
      PolygonSizeRatio:   0.1,
      PixelShake:         0.0,
      PixelSpin:          0,
      NewWidth:           0.0,
      NewHeight:          0.0,
      Greyscale:          false,
      InvertScaling:      false,
}

genart := sketch.NewSketch(img, config).Draw()

out, _ := os.Create("result.jpeg")

sketch.Encode(out, genart, enc) // encode and write to io.Writer

To programmatically change parameters, you can iteratively call DrawOnce()

...
canvas := sketch.NewSketch(img, sketch.Params{
      PolygonSidesMin: 3,
      PolygonSizeRatio: 0.1,
})

for i := 0; i < 10000; i++ {
      if i > 5000 {
            canvas.Source = img2
      }
      canvas.Stroke -= 0.01
      canvas.DrawOnce()
}

genart := canvas.Image()
sketch.Encode(out, genart, "png")

You can implement your own drawing algorithm by using DrawAt()

...
stroke := 100.0
rotate := 50.0
sides := 4
r, g, b, a := 255, 255, 255, 255

for i := 0; i < 100; i++ {
      x, y := canvas.Pixel()
      canvas.DrawAt(x, y, stroke, rotate, sides, r, g, b, a)
}
...

Authors

Adrian Agnic [ Github ]