2022-06-25 07:20:02 +00:00
|
|
|
package ring
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"image"
|
|
|
|
"image/png"
|
|
|
|
"math"
|
|
|
|
|
|
|
|
"github.com/fogleman/gg"
|
2022-10-28 15:30:54 +00:00
|
|
|
|
|
|
|
"github.com/status-im/status-go/multiaccounts"
|
2022-06-25 07:20:02 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Theme int
|
|
|
|
|
|
|
|
const (
|
|
|
|
LightTheme Theme = 1
|
|
|
|
DarkTheme Theme = 2
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
lightThemeIdenticonRingColors = []string{"#000000", "#726F6F", "#C4C4C4", "#E7E7E7", "#FFFFFF", "#00FF00", "#009800", "#B8FFBB", "#FFC413", "#9F5947", "#FFFF00", "#A8AC00", "#FFFFB0", "#FF5733", "#FF0000", "#9A0000", "#FF9D9D", "#FF0099", "#C80078", "#FF00FF", "#900090", "#FFB0FF", "#9E00FF", "#0000FF", "#000086", "#9B81FF", "#3FAEF9", "#9A6600", "#00FFFF", "#008694", "#C2FFFF", "#00F0B6"}
|
|
|
|
darkThemeIdenticonRingColors = []string{"#000000", "#726F6F", "#C4C4C4", "#E7E7E7", "#FFFFFF", "#00FF00", "#009800", "#B8FFBB", "#FFC413", "#9F5947", "#FFFF00", "#A8AC00", "#FFFFB0", "#FF5733", "#FF0000", "#9A0000", "#FF9D9D", "#FF0099", "#C80078", "#FF00FF", "#900090", "#FFB0FF", "#9E00FF", "#0000FF", "#000086", "#9B81FF", "#3FAEF9", "#9A6600", "#00FFFF", "#008694", "#C2FFFF", "#00F0B6"}
|
|
|
|
)
|
|
|
|
|
|
|
|
type DrawRingParam struct {
|
2023-03-22 17:48:42 +00:00
|
|
|
Theme Theme `json:"theme"`
|
|
|
|
ColorHash multiaccounts.ColorHash `json:"colorHash"`
|
|
|
|
ImageBytes []byte `json:"imageBytes"`
|
|
|
|
Height int `json:"height"`
|
|
|
|
Width int `json:"width"`
|
2022-06-25 07:20:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func DrawRing(param *DrawRingParam) ([]byte, error) {
|
|
|
|
var colors []string
|
|
|
|
switch param.Theme {
|
|
|
|
case LightTheme:
|
|
|
|
colors = lightThemeIdenticonRingColors
|
|
|
|
case DarkTheme:
|
|
|
|
colors = darkThemeIdenticonRingColors
|
|
|
|
default:
|
2022-08-07 07:35:54 +00:00
|
|
|
return nil, fmt.Errorf("unknown theme")
|
2022-06-25 07:20:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
dc := gg.NewContext(param.Width, param.Height)
|
|
|
|
img, _, err := image.Decode(bytes.NewReader(param.ImageBytes))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
dc.DrawImage(img, 0, 0)
|
|
|
|
|
|
|
|
ringPxSize := math.Max(1.5, float64(param.Width/24.0))
|
|
|
|
radius := (float64(param.Height) - ringPxSize) / 2
|
|
|
|
arcPos := 0.0
|
|
|
|
|
|
|
|
totalRingUnits := 0
|
|
|
|
for i := 0; i < len(param.ColorHash); i++ {
|
|
|
|
totalRingUnits += param.ColorHash[i][0]
|
|
|
|
}
|
|
|
|
unitRadLen := 2 * math.Pi / float64(totalRingUnits)
|
|
|
|
|
|
|
|
for i := 0; i < len(param.ColorHash); i++ {
|
|
|
|
dc.SetHexColor(colors[param.ColorHash[i][1]])
|
|
|
|
dc.DrawArc(float64(param.Width/2), float64(param.Height/2), radius, arcPos, arcPos+unitRadLen*float64(param.ColorHash[i][0]))
|
|
|
|
dc.SetLineWidth(ringPxSize)
|
|
|
|
dc.Stroke()
|
|
|
|
arcPos += unitRadLen * float64(param.ColorHash[i][0])
|
|
|
|
}
|
|
|
|
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
err = png.Encode(buf, dc.Image())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return buf.Bytes(), nil
|
|
|
|
}
|