-
Notifications
You must be signed in to change notification settings - Fork 1
/
avatar.go
93 lines (75 loc) · 1.83 KB
/
avatar.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package avatar
import (
"errors"
"fmt"
"sync"
"unicode"
"github.com/fogleman/gg"
)
// Generator use to generate avatar
type Generator struct {
sync.Mutex
radius float64
context *gg.Context
idx int
}
var bgColors = [...]string{`#F44336`, `#E91E63`, `#9C27B0`, `#673AB7`, `#3F51B5`, `#2196F3`, `#009688`, `#4CAF50`, `#F57F17`, `#795548`, `#424242`}
// New create new generator and load font to memory.
func New(radius float64, fontFacePath string, fontFacePoints float64) (*Generator, error) {
c := gg.NewContext(int(radius)*2, int(radius)*2)
err := c.LoadFontFace(fontFacePath, fontFacePoints)
if err != nil {
return nil, err
}
return &Generator{radius: radius, context: c, idx: 0}, nil
}
// Gen generate avatar image. if success will return image file path.
func (c *Generator) Gen(name string) (string, error) {
c.Lock()
defer c.Unlock()
if c.context == nil {
return ``, errors.New(`Generator must be initial by [func New(radius)]`)
}
fmt.Println(name)
r := []rune(name) // 可能有中文字
l := len(r)
c.context.SetRGBA(1, 1, 1, 0)
c.context.Clear() // clear context
// draw circle
c.context.DrawCircle(c.radius, c.radius, c.radius)
// random background color
if c.idx == len(bgColors) {
c.idx = 0
}
bgColor := bgColors[c.idx]
c.idx++
c.context.SetHexColor(bgColor)
c.context.Fill()
// draw name
// 巩祥啊 ---》 祥啊
// Kevin.Gong --> Ke
c.context.SetRGB(1, 1, 1)
var rs []rune
if l > 2 {
if isChineseChar(name) {
rs = r[l-2:]
} else {
rs = r[:2]
}
} else {
rs = r
}
str := string(rs)
c.context.DrawStringAnchored(str, c.radius, c.radius, 0.5, 0.5) // center
c.context.Stroke()
out := str + `.png`
return out, c.context.SavePNG(out)
}
func isChineseChar(str string) bool {
for _, r := range str {
if unicode.Is(unicode.Scripts["Han"], r) {
return true
}
}
return false
}