Skip to content

Instantly share code, notes, and snippets.

@CarsonMcKinstry
Last active July 8, 2018 13:49
Show Gist options
  • Select an option

  • Save CarsonMcKinstry/20929ffe2db6ac1ad027c3d049f36864 to your computer and use it in GitHub Desktop.

Select an option

Save CarsonMcKinstry/20929ffe2db6ac1ad027c3d049f36864 to your computer and use it in GitHub Desktop.
package main
import (
"crypto/md5"
"io"
"github.com/fogleman/gg"
)
type gridCell struct {
c byte
i int
}
type pixel struct {
h float64
v float64
}
// Identicon - the base struct of an identicon
type Identicon struct {
fileName string
hex []byte
color struct {
r int
g int
b int
}
grid []gridCell
pixelMap []pixel
img *gg.Context
}
func setFilename(i *Identicon, n string) Identicon {
i.fileName = n
return *i
}
func createHexSlice(i *Identicon) Identicon {
h := md5.New()
io.WriteString(h, i.fileName)
i.hex = h.Sum(nil)
return *i
}
func pickColor(i *Identicon) Identicon {
rgb := i.hex[0:3]
i.color.r = int(rgb[0])
i.color.g = int(rgb[1])
i.color.b = int(rgb[2])
return *i
}
func filterOddSquares(g []gridCell) []gridCell {
var filteredCells []gridCell
for _, c := range g {
if c.c%2 == 0 {
filteredCells = append(filteredCells, c)
}
}
return filteredCells
}
func makeGridCell(o []byte) []byte {
var r []byte
for _, b := range o {
r = append(r, b)
}
for i := len(o) - 2; i >= 0; i-- {
r = append(r, o[i])
}
return r
}
func buildGrid(i *Identicon) Identicon {
var cells []byte
var g []gridCell
h := i.hex
for i := 0; i < len(h); i += 3 {
end := i + 3
if end > len(h) {
end = len(h)
}
row := makeGridCell(h[i:end])
if len(row) == 5 {
cells = append(cells, row...)
}
}
for index, cell := range cells {
g = append(g, gridCell{
c: cell,
i: index,
})
}
i.grid = filterOddSquares(g)
return *i
}
func buildPixelMap(i *Identicon) Identicon {
var pm []pixel
g := i.grid
for _, cell := range g {
horizontal := cell.i % 5 * 50
vertical := cell.i / 5 * 50
pm = append(pm, pixel{
h: float64(horizontal),
v: float64(vertical),
})
}
i.pixelMap = pm
return *i
}
func draw(i *Identicon) Identicon {
dc := gg.NewContext(250, 250)
dc.DrawRectangle(0, 0, 250, 250)
dc.SetRGB(1, 1, 1)
dc.Fill()
for _, p := range i.pixelMap {
dc.DrawRectangle(p.h, p.v, 50, 50)
}
dc.SetRGB255(i.color.r, i.color.g, i.color.b)
dc.Fill()
i.img = dc
return *i
}
func createIdenticon(name string) Identicon {
var i Identicon
setFilename(&i, name)
createHexSlice(&i)
pickColor(&i)
buildGrid(&i)
buildPixelMap(&i)
draw(&i)
return i
}
func (i Identicon) save() {
i.img.SavePNG(i.fileName + ".png")
}
package main
import (
"os"
)
func main() {
var name string
if len(os.Args) > 1 {
name = os.Args[1]
} else {
name = "identicon"
}
identicon := createIdenticon(name)
identicon.save()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment