tavern/avatar/gen.go

78 lines
2.0 KiB
Go

package avatar
import (
"crypto/md5"
"fmt"
"strconv"
"strings"
"github.com/teacat/noire"
)
const avatarLocalSVG = `<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="$WIDTH" height="$HEIGHT" viewBox="0 0 $WIDTH $HEIGHT" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g>
<defs>
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="$FIRST"/>
<stop offset="100%" stop-color="$SECOND"/>
</linearGradient>
</defs>
<rect fill="url(#bg)" x="0" y="0" width="$WIDTH" height="$HEIGHT"/>
</g>
</svg>
`
const avatarRemoteSVG = `<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="$WIDTH" height="$HEIGHT" viewBox="0 0 $WIDTH $HEIGHT" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g>
<defs>
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="$FIRST"/>
<stop offset="100%" stop-color="$SECOND"/>
</linearGradient>
</defs>
<rect fill="url(#bg)" x="0" y="0" width="$WIDTH" height="$HEIGHT"/>
<polygon points="0,0 $WIDTH,0 $WIDTH,$HEIGHT" fill="#808080" />
</g>
</svg>
`
func AvatarSVG(input string, size int, local bool) string {
primary := toColor(input)
secondary := fmt.Sprintf("#%s", noire.NewHex(primary).Complement().Hex())
height := size
width := size
r := strings.NewReplacer(
"$FIRST", primary,
"$SECOND", fmt.Sprintf("#%s", secondary),
"$WIDTH", strconv.Itoa(width),
"$HEIGHT", strconv.Itoa(height),
)
if local {
return r.Replace(avatarLocalSVG)
}
return r.Replace(avatarRemoteSVG)
}
func djb2(data []byte) int32 {
var h int32 = 5381
for _, b := range data {
h = (h << 5) + h + int32(b)
}
return h
}
func toColor(input string) string {
mh := md5.New()
mh.Write([]byte(input))
h := djb2(mh.Sum(nil))
r := (h & 0xff0000) >> 16
g := (h & 0x00ff00) >> 8
b := h & 0x0000ff
return fmt.Sprintf("#%02x%02x%02x", r, g, b)
}