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  }