python制作fnt字体打包工具

当前fnt打包工具现状

当前打包fnt字体很麻烦,特别是要使用美术字生成字体集的情况,如果有一个工具可以一键打包美术字体该多好,此文章主要是参考同事许波的分享来完成,非常感谢。

制作fnt配置文件

根据之前的经验,咋们知道必须要有配置文件才能编码对应的图片,比如:a.png与A.png是不一样的,但是如果在windows目录下,这两个文件是不能同时存在的,也就是如果咋们的美术字中有这两个文件,咋们得用不同的名字来进行命名,所以需要配置文件,目录结构如下:

在这里插入图片描述fnt.py中的代码如下:
在这里插入图片描述运行后可以输出:
在这里插入图片描述
咋们words.ini中的内容如下:
在这里插入图片描述开始读取这个配置文件
在这里插入图片描述

如下是输出内容:
在这里插入图片描述配置文件保存成功

遍历工具所在目录下的所有字体文件

目录下加入字体文件夹,开始对文件夹中的图片进行遍历
在这里插入图片描述

需要在python头部加入库

 improt os

遍历文件夹

def main():
	# 读取配置文件
	readWordIni()

	# 设定遍历路径
	resourePath = "./"
	for parent,dirnames,filenames in os.walk(resourePath):
		print(parent,"||",dirnames,"||",filenames)
		# dirnames为当前目录下的文件夹列表,遍历她
		for dir_list in dirnames:
			srcpath = resourePath + dir_list
			print("start dir name:",srcpath)

			# 创建一个输出目录
			output_path_name = srcpath+os.sep+"output"
			# print(output_path_name)
			if not os.path.exists(output_path_name):
				os.makedirs(output_path_name)

			

		# 只取第一层
		break

就会再每个字体的目录下创建output输出文件夹,开始遍历字体,如果匹配到字体的命名与配置中的相同,则用对应的配置来取代原有图片的名字作为id

			# 创建转化列表
			convert_list=dict()
			fnt_name = os.path.basename(srcpath)
			# 存对应的ascii码
			list = os.listdir(srcpath)
			#列出文件夹下所有的目录与文件
			for i in range(0,len(list)):
				basename = list[i]

				# 判断是否是png
				isPng = basename[-4:]
				if isPng != ".png":
					continue

				# 保存图片的完整路径,后面为生成图片集做准备
				filename = srcpath+os.sep+basename
				# 取出文件名
				font=basename[:basename.rfind(".")]
				# 查找文件名在配置中是否有相关设定
				if str(font) in fnt_convert_word :
					# print("font",font,fnt_convert_word[str(font)])
					font = fnt_convert_word[str(font)]

				# 将对应的font(有可能是文件名也有可能是配置的名字)转化为ascii码
				try:
					ascii_code = ord(font)
				except TypeError as e:
					print("font define name:" + font + " error !!")
					return

				# 存储路径对应的ascii码
				convert_list[filename]=ascii_code
				continue

开始根据文件的路径及对应的ascii码来计算图片总面积
在这里插入图片描述读取目录下所有图片,计算出其中最大尺寸的图片,根据max_width与max_height计算出所有图片所占用的最大图片尺寸,而对面积求平方根就是相同面积的正方行的边长

def createFntSet(fnt_name,convert_list,output_path_name):
	if len(convert_list)>=1 :
		# 存储单张图片的最大高度与最大宽度
		global max_width
		global max_height
		global colCount
		global rowCount
		max_height=0
		max_width=0

		# 存储图片的相关定义
		fnt_define_item = list()
		# 存储图片的相关定义的字典
		fnt_define_dic = {}
		# 遍历列表中的所有图片,找到最大宽度与高度
		for key in convert_list.keys():
			image = Image.open(key)
			image_size= image.size
			max_width=max(max_width,image_size[0])
			max_height=max(max_height,image_size[1])

			# 存储数据
			fnt_define_item_data=dict()
			fnt_define_item.append(fnt_define_item_data)
			fnt_define_dic[key] = fnt_define_item_data

			fnt_define_item_data["id"]=convert_list[key]
			fnt_define_item_data["width"]=str(image_size[0])
			fnt_define_item_data["height"]=str(image_size[1])
			fnt_define_item_data["xoffset"]=str(0)
			fnt_define_item_data["yoffset"]=str(0)
			fnt_define_item_data["xadvance"]=str(image_size[0])
			fnt_define_item_data["page"]=str(0)
			fnt_define_item_data["chnl"]=str(0)
			# 去除图片的ascii转成字母
			fnt_define_item_data["letter"]=chr(int(convert_list[key]))

		# 计算图片的横向与纵向的数量
		totalCount = len(convert_list)
		# 长*宽是面积,这里算的是最大方块面积再乘以数量就是总面积,总面积开平方根是指该面积所构成的正方形的边长
		# 边长除以宽度则是数量
		colCount =  int(math.ceil(math.sqrt(max_height*max_width*totalCount*1.0)/max_width))
		rowCount = int(math.ceil(len(convert_list)*1.0/colCount))
		print("计算出图片横向纵向的数量:",colCount,rowCount)

		# 图片的索引,代表当前是处理的第几张图片
		index=0
		# 上面存储完图片的相关数据后,没有存储路径,下面再次计算图片的位置
		for key in convert_list.keys():
			fnt_item_data = fnt_define_dic[key]

			# 开始计算位置
			fnt_item_data["x"]=str((index%colCount)*max_width)
			fnt_item_data["y"]=str(int(index/colCount)*max_height)

			index += 1

		fnt_define=dict()
		fnt_define["data"]=fnt_define_item
		fnt_define["size"]=str(max_width)
		fnt_define["lineHeight"]=str(max_height)
		fnt_define["base"]=str(max_width)
		fnt_define["scaleW"]=str(max_width*colCount)
		fnt_define["scaleH"]=str(max_height*rowCount)
		image_name=fnt_name+".png"
		fnt_define["file"]=image_name
		fnt_define["count"]=len(convert_list)

		# 保存fnt数据文件
		fnt_name=output_path_name+"/"+fnt_name+".fnt"
		saveFntData(fnt_name,fnt_define)

		# 保存png图片文件
		image_name=output_path_name+"/"+image_name
		print("ajdkj",max_width,max_height,colCount)
		savePng(image_name,convert_list,fnt_define_dic)

生成fnt数据文件

def saveFntData(fnt_name,fnt_define):
	# 创建一个文件
	write_file=open(fnt_name,"w")
	write_file = codecs.open(fnt_name,"w","utf-8")
	#face="Arial”,字体为”Arial”
	# size=32:大小为32像素
	# bold=0 :不加粗
	# italic=0:不使用斜体
	# charset="": charset是编码字符集,这里没有填写值即使用默认,
	# unicode=0:不使用Unicode
	# stretchH=100:纵向缩放百分比
	# smooth=1 :开启平滑
	# aa=1:开启抗锯齿
	# padding=0,0,0,0:内边距,文字与边框的空隙。
	# spacing=1,1 :外边距,就是相临边缘的距离。
	head_msg1="""info face="%s" size=%s bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=2,2 outline=0\n""" % (face,fnt_define["size"])
	write_file.write(head_msg1)
	# lineHeight=37:行高,如果遇到换行符时,绘制字的位置坐标的Y值在换行后增加的像素值。
	# base=28 :字的基本大小
	# scaleW=512 :图片大小
	# scaleH=512:图片大小
	# pages=1 :此种字体共用到几张图。
	# packed=0:图片不压缩
	head_msg2 ="""common lineHeight=%s base=%s scaleW=%s scaleH=%s pages=1 packed=0 alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0\n""" % (fnt_define["lineHeight"],fnt_define["base"],fnt_define["scaleW"],fnt_define["scaleH"])
	write_file.write(head_msg2)
	# //第一页,文件名称是”bitmapFontChinese.png”
	# page id=0 file="bitmapFontChinese.png"
	head_msg3 = """page id=0 file="%s"\n""" % (fnt_define["file"])
	write_file.write(head_msg3)
	# 第四行是当前贴图中所容纳的文字数量
	head_msg4 = """chars count=%s\n""" % (fnt_define["count"])
	write_file.write(head_msg4)

	for i in range(0,int(fnt_define["count"])):
		data=fnt_define["data"][i]
		line="char id=%s x=%s y=%s width=%s height=%s xoffset=%s yoffset=%s xadvance=%s page=%s chnl=%s letter=\"%s\"\n" %(data["id"],data["x"],data["y"],data["width"],data["height"],data["xoffset"],data["yoffset"],data["xadvance"],data["page"],data["chnl"],data["letter"])
		write_file.write(line)

保存图片

def savePng(image_name,convert_list,fnt_define_dic):
	# 计算图片的最大尺寸
	outW=max_width*colCount
	outH=max_height*rowCount

	# 创建输出图片
	toImage = Image.new('RGBA', (outW, outH))

	# 开始保存图片
	index = 0
	for key in convert_list.keys():
		fromImage=Image.open(key)

		item_def = fnt_define_dic[key]
		toImage.paste(fromImage,( int(item_def["x"]),int(item_def["y"])))

	toImage.save(image_name)

效果如下:
在这里插入图片描述在这里插入图片描述在这里插入图片描述

详情可以参考附件

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值