「Go工具箱」想生成文字头像,就用这个工具:letteravatar

791 阅读4分钟

小猫坐沙发.webp 大家好,我是渔夫子。本号新推出「Go工具箱」系列,意在给大家分享使用go语言编写的、实用的、好玩的工具。

使用过钉钉的同学肯定都注意到过,钉钉的头像默认是以姓名的文字生成的。那么,今天就给大家推荐一个可以轻松用文字生成头像的工具:letteravatar。该工具的作者也是我们上篇推荐的图像处理工具imaging的作者。

以下是该工具的基本档案:

letteravatar小档案
star122used by-
contributors-工具分类图像处理
功能简介可以将文字生成一个100*100的头像
相关知识FreeType、TrueType

从星标上来看,该工具并不知名。但这里值得学习的是有两个知识点:FreeType和TrueType。

FreeType和TrueType FreeType是一个可移植的,高效的字体引擎。TrueType是一个字体。 字体在电脑上的显示有两种方式:点阵和矢量。对于一个字,点阵字体保存的是每个点的渲染信息。这个方式的劣势在于保存的数据量非常大,并且对放大缩小等操作支持不好。因此出现了矢量字体。 对于一个字,矢量字体保存的是字的绘制公式。这个绘制公式包括了字体轮廓(outline)和字体精调(hint)。字体轮廓使用贝塞尔曲线来绘制出字的外部线条。在大分辨率的情况下就需要对字体进行精调了。这个绘制字的公式就叫做字体数据(glyph)。在字体文件中,每个字对应一个glyph。那么字体文件中就存在一个字符映射表(charmap)。 对于矢量字体,其中用的最为广泛的是TrueType。它的扩展名一般为otf或者ttf。在windows,linux,osx上都得到广泛支持。我们平时看到的.ttf和.ttc的字体文件就是TrueType字体。其中ttc是多个ttf的集合文件(collection)。

TrueType只是一个字体,而要让这个字体在屏幕上显示,就需要字体驱动库了。其中FreeType就是这么一种高效的字体驱动引擎。一个汉字从字体到显示,FreeType大致有几个步骤:加载字体、设置字体大小、加载glyph、字体对应大小等转换、绘制字体。 这里特别注意的是FreeType并不只能驱动TrueType字体,它还可以驱动其他各种矢量字体,甚至也可以驱动点阵字体

安装 go get github.com/disintegration/letteravatar

基本使用 生成一个100*100大小的以字母‘A’为图像的头像:

img, err := letteravatar.Draw(100, 'A', nil)

当然,我们还可以自定义字体、背景颜色、字体颜色等。如下,通过letteravatar.Options参数进行设置:

type Options struct {
    Font        *truetype.Font //指定字体,默认字体是不支持中文显示的
    Palette     []color.Color //指定背景的调色板
    LetterColor color.Color // 指定文字的颜色
    PaletteKey  string // 通过该key,可以hash到Palette中指定的背景颜色
}

比如,我们如下定义,背景色只使用以下三种颜色,则可以对Options参数进行如下设置:

img, err := letteravatar.Draw(100, 'A', &letteravatar.Options{
	Palette: []color.Color{
		color.RGBA{255, 0, 0, 255},
		color.RGBA{0, 255, 0, 255},
		color.RGBA{0, 0, 255, 255},
	},
})

该包默认的字体是不支持中文绘制的。所以,如果想使用中文绘制头像,就需要下载中文的ttf字体,并通过Options中的Font参数指定。本文使用思源宋体的字体文件来进行中文的绘制。如下:

package main

import (
	"fmt"
	"github.com/golang/freetype"
	"image/png"
	"io/ioutil"
	"log"
	"os"
	"unicode/utf8"

	"github.com/disintegration/letteravatar"
)

func main() {
	fontFile, _ := ioutil.ReadFile("./SourceHanSerifSC-VF.ttf")
	font, _ := freetype.ParseFont(fontFile)
	options := &letteravatar.Options{
		Font: font,
	}
	name := "渔夫子"
	firstLetter, _ := utf8.DecodeRuneInString(name)

	img, err := letteravatar.Draw(75, firstLetter, options)
	if err != nil {
		log.Fatal(err)
	}

	file, err := os.Create(name + ".png")
	if err != nil {
		log.Fatal(err)
	}

	err = png.Encode(file, img)
	if err != nil {
		log.Fatal(err)
	}	
}

生成效果如下:

渔夫子.png

最后,给一个用英文字母生成的示例以及生成效果:

Alice.pngBob.pngCarol.pngDave.pngEve.pngFrank.pngGloria.pngHenry.pngIsabella.pngJames.pngЖозефина.pngЯрослав.png

package main

import (
	"image/png"
	"log"
	"os"
	"unicode/utf8"

	"github.com/disintegration/letteravatar"
)

var names = []string{
	"Alice",
	"Bob",
	"Carol",
	"Dave",
	"Eve",
	"Frank",
	"Gloria",
	"Henry",
	"Isabella",
	"James",
	"Жозефина",
	"Ярослав",
}

func main() {
	for _, name := range names {
		firstLetter, _ := utf8.DecodeRuneInString(name)

		img, err := letteravatar.Draw(75, firstLetter, nil)
		if err != nil {
			log.Fatal(err)
		}

		file, err := os.Create(name + ".png")
		if err != nil {
			log.Fatal(err)
		}

		err = png.Encode(file, img)
		if err != nil {
			log.Fatal(err)
		}
	}
}

更多项目详情请查看如下链接。

开源项目地址:github.com/disintegrat…

开源项目作者:Grigory Dryapak

---特别推荐---

特别推荐:关注「Go学堂」,领取《100个go常见的错误》pdf文档。