github.com/status-im/status-go@v1.1.0/protocol/identity/ring/ring.go (about) 1 package ring 2 3 import ( 4 "bytes" 5 "fmt" 6 "image" 7 "image/png" 8 "math" 9 10 "github.com/fogleman/gg" 11 12 "github.com/status-im/status-go/multiaccounts" 13 ) 14 15 type Theme int 16 17 const ( 18 LightTheme Theme = 1 19 DarkTheme Theme = 2 20 ) 21 22 var ( 23 lightThemeIdenticonRingColors = []string{ 24 "#000000", "#726F6F", "#C4C4C4", "#E7E7E7", "#FFFFFF", "#00FF00", 25 "#009800", "#B8FFBB", "#FFC413", "#9F5947", "#FFFF00", "#A8AC00", 26 "#FFFFB0", "#FF5733", "#FF0000", "#9A0000", "#FF9D9D", "#FF0099", 27 "#C80078", "#FF00FF", "#900090", "#FFB0FF", "#9E00FF", "#0000FF", 28 "#000086", "#9B81FF", "#3FAEF9", "#9A6600", "#00FFFF", "#008694", 29 "#C2FFFF", "#00F0B6"} 30 darkThemeIdenticonRingColors = []string{ 31 "#000000", "#726F6F", "#C4C4C4", "#E7E7E7", "#FFFFFF", "#00FF00", 32 "#009800", "#B8FFBB", "#FFC413", "#9F5947", "#FFFF00", "#A8AC00", 33 "#FFFFB0", "#FF5733", "#FF0000", "#9A0000", "#FF9D9D", "#FF0099", 34 "#C80078", "#FF00FF", "#900090", "#FFB0FF", "#9E00FF", "#0000FF", 35 "#000086", "#9B81FF", "#3FAEF9", "#9A6600", "#00FFFF", "#008694", 36 "#C2FFFF", "#00F0B6"} 37 ) 38 39 type DrawRingParam struct { 40 Theme Theme `json:"theme"` 41 ColorHash multiaccounts.ColorHash `json:"colorHash"` 42 ImageBytes []byte `json:"imageBytes"` 43 Height int `json:"height"` 44 Width int `json:"width"` 45 RingWidth float64 `json:"ringWidth"` 46 } 47 48 func DrawRing(param *DrawRingParam) ([]byte, error) { 49 var colors []string 50 switch param.Theme { 51 case LightTheme: 52 colors = lightThemeIdenticonRingColors 53 case DarkTheme: 54 colors = darkThemeIdenticonRingColors 55 default: 56 return nil, fmt.Errorf("unknown theme") 57 } 58 59 dc := gg.NewContext(param.Width, param.Height) 60 img, _, err := image.Decode(bytes.NewReader(param.ImageBytes)) 61 if err != nil { 62 return nil, err 63 } 64 dc.DrawImage(img, 0, 0) 65 66 radius := (float64(param.Height) - param.RingWidth) / 2 67 arcPos := 0.0 68 69 totalRingUnits := 0 70 for i := 0; i < len(param.ColorHash); i++ { 71 totalRingUnits += param.ColorHash[i][0] 72 } 73 unitRadLen := 2 * math.Pi / float64(totalRingUnits) 74 75 for i := 0; i < len(param.ColorHash); i++ { 76 dc.SetHexColor(colors[param.ColorHash[i][1]]) 77 dc.DrawArc(float64(param.Width/2), float64(param.Height/2), radius, arcPos, arcPos+unitRadLen*float64(param.ColorHash[i][0])) 78 dc.SetLineWidth(param.RingWidth) 79 dc.SetLineCapButt() 80 dc.Stroke() 81 arcPos += unitRadLen * float64(param.ColorHash[i][0]) 82 } 83 84 buf := new(bytes.Buffer) 85 err = png.Encode(buf, dc.Image()) 86 if err != nil { 87 return nil, err 88 } 89 90 return buf.Bytes(), nil 91 }