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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/652894.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【PG16】后 EL 7 时代,PG 16 如何在 CentOS 7 上运行

↑ 关注“少安事务所”公众号&#xff0c;欢迎⭐收藏&#xff0c;不错过精彩内容~ ★ 本文写于 2023-09-29 PostgreSQL 16 Released 9/14, PostgreSQL 16 正式发布。从发布公告^1 和 Release Notes^2 可以看到 PG16 包含了诸多新特性和增强改进。 性能提升&#xff0c;查询计划…

XPosed项目的接入、模版制作、改名全过程

XPosed项目的接入、模版制作、改名全过程 写在前面 之前写过这篇Xposed Hook 过登录密码验证配置开发Xposed项目的文章&#xff0c;这次的接入使用的是当前最新版Android Studio&#xff0c;接入稍微有些差别&#xff0c;也记录下。 本篇文章主要是写关于XP项目接入、制作XP模…

SQL——SELECT相关的题目(力扣难度等级:简单)

目录 197、上升的温度 577、员工奖金 586、订单最多的客户 596、超过5名学生的课 610、判断三角形 620、有趣的电影 181、超过经理收入的员工 1179、重新格式化部门表&#xff08;行转列&#xff09; 1280、学生参加各科测试的次数 1965、丢失信息的雇员 1068、产品销售分…

教你网站如何免费实现https

想要实现https访问最简单有效的的方法就是安装SSL证书。只要证书正常安装上以后&#xff0c;浏览器就不会出现网站不安全提示或者访问被拦截的情况。下面我来教大家怎么去获取免费的SSL证书&#xff0c;又如何安装证书实现https访问。 一、选择免费SSL证书提供商 有多家机构提…

CLI举例:负载分担场景下的源NAT配置(主备设备共用同一个地址池)

CLI举例&#xff1a;负载分担场景下的源NAT配置&#xff08;主备设备共用同一个地址池&#xff09; 组网需求 如图1所示&#xff0c;企业的两台FW的业务接口都工作在三层&#xff0c;上下行分别连接路由器。FW与上下行路由器之间运行OSPF协议。上行接口连接同一个ISP。 现在希…

word-主控文档、文档拆分及标书编写技巧建议

一、主控文档 视图-大纲视图-显示文档-插入子文档 子文档一旦更新&#xff0c;主文档也会更新。更新主文档&#xff0c;子文档也会更新 需要注意&#xff0c;不可修改子文档名字 二、上交文件 显示文档-折叠子文档-只显示一级-取消链接-关闭大纲视图-保存 三、文档拆分 根…

数据结构算法题day03

数据结构算法题day03 题目 题目 2.设计一个高效算法&#xff0c;将顺序表L的所有元素逆置&#xff0c;要求算法的空间复杂度为O(1)算法思想&#xff1a; 1、常规的解法&#xff1a; Void reverse (sqlist &L){Elemtype temp; //辅助变量for(i 0,i < L.length; i){temp…

Thinkphp5响应式进销存仓库管理系统

随着企业规模的不断扩大和市场竞争的日益激烈&#xff0c;进销存管理在企业的运营中扮演着越来越重要的角色。为了提高企业的运营效率&#xff0c;降低库存成本&#xff0c;提升客户满意度&#xff0c;越来越多的企业开始引入进销存仓库管理系统。 进销存仓库管理系统是一种集…

【机器学习】深入探索机器学习:线性回归算法的原理与应用

❀线性回归算法 &#x1f4d2;1. 引言&#x1f4d2;2. 线性回归的基本原理&#x1f389;回归方程&#x1f389;最小化误差&#x1f389;线性回归的假设条件 &#x1f4d2;3. 线性回归算法的实现&#x1f4d2;4. 线性回归算法的特征工程&#x1f4d2;5. 线性回归模型评估与优化&…

蓝桥杯练习系统(算法训练)ALGO-932 低阶行列式计算

资源限制 内存限制&#xff1a;64.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 给出一个n阶行列式(1<n<9)&#xff0c;求出它的值。 输入格式 第一行给出两个正整数n,p&#xff1b;   接下来n行&…

oracle准确记录数据提交时间

注意&#xff1a;mysql中的默认值同样记录的是dml操作发出时的时间&#xff0c;并且没有找到mysql中准确记录commit时间的方法。 oracle中数据发生变动时&#xff0c;如何准确记录发生变动时的时间。一般会使用ts字段&#xff0c;该字段使用默认值&#xff0c;default to_char…

JeeSite 4.x and 5.x快速开发平台前端技术探索与实践

一、引言 随着企业信息化建设的不断推进&#xff0c;对于快速、高效、安全的企业级应用需求日益增长。JeeSite作为一款企业级快速开发平台&#xff0c;以其强大的后端功能和灵活的前端架构&#xff0c;为开发者提供了强大的支持。本文旨在探讨JeeSite快速开发平台在前端技术方…

c++——模板初始识

1.函数模板 我们经常用到Swap函数交换两个值。由于需要交换的数据的类型不同&#xff0c;我们就需要写不同参数类型的同名函数&#xff0c;也就是函数重载&#xff1a; 然而这三个函数的逻辑是一样的&#xff0c;写这么多有些多此一举&#xff0c;通过函数模版可以写一个通用…

摸鱼大数据——Hive表操作——文件数据的导入和导出

数据导入和导出 1、文件数据导入 1.1 直接上传文件 window页面上传 需求: 已知emp1.txt文件在windows/mac系统,要求使用hdfs保存此文件 并且使用hivesql建表关联数据 use day06; ​ -- 1- 创建Hive表 create table emp1 (id int,name string,salary int,dept string )row for…

CUDA_VISIBLE_DEVICES‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。

问题&#xff1a; 命令行出现CUDA_VISIBLE_DEVICES0 python trainer.py这种命令 这是Linux可以的&#xff0c;但是Windows不行。 解决方案&#xff1a; 这条命令的含义是指定某个GPU来运行程序&#xff0c;我们可以在程序开头添加指定GPU的代码&#xff0c;效果是一样的&…

xLSTM——解析扩展长短期记忆的网络算法与应用

1.概述 二十多年来&#xff0c; 塞普霍赫赖特 创举 长短期记忆 (LSTM) 架构在许多深度学习突破和实际应用中发挥了重要作用。从生成自然语言到为语音识别系统提供动力&#xff0c;LSTM 一直是人工智能革命背后的驱动力。 然而&#xff0c;即使是 LSTM 的创建者也认识到它们固…

【Sql Server】随机查询一条表记录,并重重温回顾下存储过程的封装和使用

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言随机查询语…

Visual Studio +Resharp,让你在C#编程界一骑绝尘!【文末送2024C#入门到精通教程视频+源码C#.NET全栈开发高级VIP班[完结】

目录 前言 一、Visual Studio&#xff1a;C#开发的强大后盾 二、ReSharper&#xff1a;智能代码编辑器的典范 三、Visual Studio ReSharper&#xff1a;一骑绝尘的编程组合 四、如何发挥最大效能 五、结论 文末福利&#xff1a; 文末有福利 前言 在C#编程领域&#x…

情感分析及数据集代码解析

15.1. 情感分析及数据集 — 动手学深度学习 2.0.0 documentation (d2l.ai) 代码 import os import torch from torch import nn from d2l import torch as d2l#save d2l.DATA_HUB[aclImdb] (http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz,01ada507287d828…

【Altium Designer】安装教程

一、软件下载 二、软件安装 三、授权文件激活 一、软件下载 Altium Designer官网下载 二、软件安装 1.解压完下载好的软件&#xff0c;鼠标右击【OfflineSetup_Altium_Designer_Public_24_5_1】安装程序&#xff0c;选择【以管理员身份运行】。 2.语言选择【Chinese】&#…