github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/services/users/profile_picture.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package users 5 6 import ( 7 "bytes" 8 "hash/fnv" 9 "image" 10 "image/color" 11 "image/draw" 12 "image/png" 13 "io/ioutil" 14 "path/filepath" 15 "strings" 16 17 "github.com/golang/freetype" 18 "github.com/golang/freetype/truetype" 19 "github.com/masterhung0112/hk_server/v5/model" 20 "github.com/masterhung0112/hk_server/v5/utils/fileutils" 21 ) 22 23 const ( 24 imageProfilePixelDimension = 128 25 ) 26 27 func (us *UserService) GetDefaultProfileImage(user *model.User) ([]byte, error) { 28 if user.IsBot { 29 return botDefaultImage, nil 30 } 31 32 return createProfileImage(user.Username, user.Id, *us.config().FileSettings.InitialFont) 33 } 34 35 func createProfileImage(username string, userID string, initialFont string) ([]byte, error) { 36 colors := []color.NRGBA{ 37 {197, 8, 126, 255}, 38 {227, 207, 18, 255}, 39 {28, 181, 105, 255}, 40 {35, 188, 224, 255}, 41 {116, 49, 196, 255}, 42 {197, 8, 126, 255}, 43 {197, 19, 19, 255}, 44 {250, 134, 6, 255}, 45 {227, 207, 18, 255}, 46 {123, 201, 71, 255}, 47 {28, 181, 105, 255}, 48 {35, 188, 224, 255}, 49 {116, 49, 196, 255}, 50 {197, 8, 126, 255}, 51 {197, 19, 19, 255}, 52 {250, 134, 6, 255}, 53 {227, 207, 18, 255}, 54 {123, 201, 71, 255}, 55 {28, 181, 105, 255}, 56 {35, 188, 224, 255}, 57 {116, 49, 196, 255}, 58 {197, 8, 126, 255}, 59 {197, 19, 19, 255}, 60 {250, 134, 6, 255}, 61 {227, 207, 18, 255}, 62 {123, 201, 71, 255}, 63 } 64 65 h := fnv.New32a() 66 h.Write([]byte(userID)) 67 seed := h.Sum32() 68 69 initial := string(strings.ToUpper(username)[0]) 70 71 font, err := getFont(initialFont) 72 if err != nil { 73 return nil, DefaultFontError 74 } 75 76 color := colors[int64(seed)%int64(len(colors))] 77 dstImg := image.NewRGBA(image.Rect(0, 0, imageProfilePixelDimension, imageProfilePixelDimension)) 78 srcImg := image.White 79 draw.Draw(dstImg, dstImg.Bounds(), &image.Uniform{color}, image.Point{}, draw.Src) 80 size := float64(imageProfilePixelDimension / 2) 81 82 c := freetype.NewContext() 83 c.SetFont(font) 84 c.SetFontSize(size) 85 c.SetClip(dstImg.Bounds()) 86 c.SetDst(dstImg) 87 c.SetSrc(srcImg) 88 89 pt := freetype.Pt(imageProfilePixelDimension/5, imageProfilePixelDimension*2/3) 90 _, err = c.DrawString(initial, pt) 91 if err != nil { 92 return nil, UserInitialsError 93 } 94 95 buf := new(bytes.Buffer) 96 97 if imgErr := png.Encode(buf, dstImg); imgErr != nil { 98 return nil, ImageEncodingError 99 } 100 101 return buf.Bytes(), nil 102 } 103 104 func getFont(initialFont string) (*truetype.Font, error) { 105 // Some people have the old default font still set, so just treat that as if they're using the new default 106 if initialFont == "luximbi.ttf" { 107 initialFont = "nunito-bold.ttf" 108 } 109 110 fontDir, _ := fileutils.FindDir("fonts") 111 fontBytes, err := ioutil.ReadFile(filepath.Join(fontDir, initialFont)) 112 if err != nil { 113 return nil, err 114 } 115 116 return freetype.ParseFont(fontBytes) 117 }