avatar.go (view raw)
1//
2// Copyright (c) 2019 Ted Unangst <tedu@tedunangst.com>
3//
4// Permission to use, copy, modify, and distribute this software for any
5// purpose with or without fee is hereby granted, provided that the above
6// copyright notice and this permission notice appear in all copies.
7//
8// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
16package main
17
18import (
19 "bufio"
20 "bytes"
21 "crypto/sha512"
22 "image"
23 "image/png"
24 "log"
25 "strconv"
26 "strings"
27)
28
29var avatarcolors = [4][4]byte{
30 {16, 0, 48, 255},
31 {48, 0, 96, 255},
32 {72, 0, 144, 255},
33 {96, 0, 192, 255},
34}
35
36func loadAvatarColors() {
37 var colors string
38 getconfig("avatarcolors", &colors)
39 if colors == "" {
40 return
41 }
42 r := bufio.NewReader(strings.NewReader(colors))
43 for i := 0; i < 4; i++ {
44 l, _ := r.ReadString(' ')
45 for l == " " {
46 l, _ = r.ReadString(' ')
47 }
48 l = strings.Trim(l, "# \n")
49 if len(l) == 6 {
50 l = l + "ff"
51 }
52 c, err := strconv.ParseUint(l, 16, 32)
53 if err != nil {
54 log.Printf("error reading avatar color %d: %s", i, err)
55 continue
56 }
57 avatarcolors[i][0] = byte(c >> 24 & 0xff)
58 avatarcolors[i][1] = byte(c >> 16 & 0xff)
59 avatarcolors[i][2] = byte(c >> 8 & 0xff)
60 avatarcolors[i][3] = byte(c >> 0 & 0xff)
61 }
62}
63
64func genAvatar(name string) []byte {
65 h := sha512.New()
66 h.Write([]byte(name))
67 s := h.Sum(nil)
68 img := image.NewNRGBA(image.Rect(0, 0, 64, 64))
69 for i := 0; i < 64; i++ {
70 for j := 0; j < 64; j++ {
71 p := i*img.Stride + j*4
72 xx := i/16*16 + j/16
73 x := s[xx]
74 if x < 64 {
75 img.Pix[p+0] = avatarcolors[0][0]
76 img.Pix[p+1] = avatarcolors[0][1]
77 img.Pix[p+2] = avatarcolors[0][2]
78 img.Pix[p+3] = avatarcolors[0][3]
79 } else if x < 128 {
80 img.Pix[p+0] = avatarcolors[1][0]
81 img.Pix[p+1] = avatarcolors[1][1]
82 img.Pix[p+2] = avatarcolors[1][2]
83 img.Pix[p+3] = avatarcolors[1][3]
84 } else if x < 192 {
85 img.Pix[p+0] = avatarcolors[2][0]
86 img.Pix[p+1] = avatarcolors[2][1]
87 img.Pix[p+2] = avatarcolors[2][2]
88 img.Pix[p+3] = avatarcolors[2][3]
89 } else {
90 img.Pix[p+0] = avatarcolors[3][0]
91 img.Pix[p+1] = avatarcolors[3][1]
92 img.Pix[p+2] = avatarcolors[3][2]
93 img.Pix[p+3] = avatarcolors[3][3]
94 }
95 }
96 }
97 var buf bytes.Buffer
98 png.Encode(&buf, img)
99 return buf.Bytes()
100}