go使用letteravatar生成圆形透明头像图标

官网地址:GitHub - disintegration/letteravatar: Letter avatar generation for Go

我对其中函数改了一下,支持多个字符,效果如下:

func TestCreateAvatar(t *testing.T) {
	GenerateAvatar("Bird Fish", 0, "Bird.png")
	GenerateAvatar("飞鸟真人", 1, "飞鸟.png")
	GenerateAvatar("Жозефина", 1, "1.png")
	GenerateAvatar("Ярослав", 1, "2.png")
	GenerateAvatar("ちびまる子ちゃん", 1, "日语.png")

}

其中把源码放到自己目录下,改其中的函数,将rune类型参数改为string,

然后自己加个蒙版:

package utils

import (
	"birdtalk/server/utils/myavatar"
	"fmt"
	"github.com/fogleman/gg"
	"github.com/golang/freetype/truetype"
	"image"
	"image/color"
	"image/draw"
	"image/png"
	"os"
	"unicode/utf8"
)

func GenerateAvatar(name string, gender int, saveFilePath string) error {

	onceShort.Do(func() {
		initFont()
	})

	// 生成圆形图标
	avatar, err := generateAvatar(name, 100, gender)
	if err != nil {
		return err
	}

	// 创建相同尺寸的圆形蒙版
	mask := createCircularMask(avatar.Bounds())

	// 创建一个新的透明背景图像
	bgImg := image.NewRGBA(avatar.Bounds())

	// 使用圆形蒙版将文字图标覆盖到透明背景图像上
	draw.DrawMask(bgImg, bgImg.Bounds(), avatar, image.Point{}, mask, image.Point{}, draw.Over)

	// 保存图像到文件
	file, err := os.Create(saveFilePath)
	if err != nil {
		return err
	}
	defer file.Close()

	err = png.Encode(file, bgImg)
	if err != nil {
		return err
	}

	//fmt.Println("Avatar saved as avatar.png")
	return nil
}

// LoadFontToMemory 加载字体文件到内存中,返回一个粗体
func loadFontToMemory(fontPath string) (*truetype.Font, error) {
	// Read the font file into memory
	fontBytes, err := os.ReadFile(fontPath)
	if err != nil {
		return nil, err
	}

	// Parse the font file
	font, err := truetype.Parse(fontBytes)
	if err != nil {
		return nil, err
	}

	return font, nil
}

var defaultFont *truetype.Font = nil

func initFont() {
	strFilePath := "D:\\GBuild\\\utils\\SourceHanSans-VF.ttf"
	//strFilePath = "C:\\Windows\\Fonts\\simfang.ttf"
	font, err := loadFontToMemory(strFilePath)
	if err != nil {
		return
	}
	defaultFont = font
}

// createCircularMask 创建一个圆形蒙版,与指定的边界大小相同
func createCircularMask(bounds image.Rectangle) *image.Alpha {
	dc := gg.NewContext(bounds.Dx(), bounds.Dy())
	dc.DrawCircle(float64(bounds.Dx())/2, float64(bounds.Dy())/2, float64(bounds.Dx())/2)
	dc.Fill()

	mask := image.NewAlpha(bounds)
	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			_, _, _, a := dc.Image().At(x, y).RGBA()
			mask.Set(x, y, color.Alpha{A: uint8(a >> 8)})
		}
	}
	return mask
}

func generateAvatar(name string, sz int, gender int) (image.Image, error) {

	if defaultFont == nil {
		// 汉语会出错
	}
	myColor := color.RGBA{0x7f, 0xd3, 0xfa, 0xff} // 蓝色
	if gender == 0 {
		myColor = color.RGBA{0xf6, 0xa1, 0xbe, 0xff} // 粉色
	}
	options := &myavatar.Options{
		Font: defaultFont,
		Palette: []color.Color{
			myColor,
		},
	}

	first6Letter := TakeFirstCharacters(name)
	fmt.Println("返回:", first6Letter)
	avatar, err := myavatar.Draw(sz, first6Letter, options)

	if err != nil {
		return nil, err
	}

	return avatar, nil
}

// TakeFirstNRunes 返回字符串的前N个字符,确保总字节数不超过4个字节
// TakeFirstCharacters 根据字符类型取字符串的前N个字符
func TakeFirstCharacters(str string) string {

	result := ""
	count := 0
	for len(str) > 0 {
		r, size := utf8.DecodeRuneInString(str)
		//fmt.Printf("字符: %c, 字节数: %d\n", r, size)
		if (count + size) > 6 {
			break
		} else {
			result += string(r)
			count += size
		}

		str = str[size:] // 将已解码的字符从字符串中去除
	}

	return result
}

func TakeFirstNRunes(str string, n int) string {
	var result string
	var bytesCount int
	for _, runeValue := range str {
		runeSize := utf8.RuneLen(runeValue)
		if bytesCount+runeSize > 4 {
			break
		}
		bytesCount += runeSize
		result += string(runeValue)
		if bytesCount == 4 {
			break
		}
	}
	return result
}

其中字体是从如下地址找的开源字体:Releases · adobe-fonts/source-han-sans · GitHub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值