在计算机发明之初仅实现了点阵字库,那时显示的仅有一些数字字母,数量相对于象形文字是极低的,在物联网开发中经常会遇到显示的需求,如室外的LED点阵大屏、墨水屏、单色屏等等场景,对于不太复杂显示一般不会使用GUI库,在没有GUI库的情况如何显示动态显示汉字这类象形文字呢?在嵌入式中一般做法是去外挂一个字库芯片,在这里面存储了大部分用到会或者不会的字符的点阵数据,这个类芯片的字体和字号都是固定的,够显示的字符数量有效,整个交互只能围绕这几种字号展开设计;除此之外我们还可以逆向方式使用已有的矢量字体去生成任意字体、任意字号的点阵字库。
1. 什么是点阵字库
点阵字库也称为像素字库,每个像素点都存储一个灰度数据,这是存储字库的一种编码格式,我们可以借助windows绘图程序手动生成一个点阵汉字(如下图所示),这是在32*32像素的位图上放置了一个汉字-“老”,放置确定后绘图程序会对汉字进行灰度化操作,当然也可以用通过设置属性转换成纯黑白的位图数据;

上面点阵字库显示的效果并不好,这是由于我们放大了点阵字库,缩小后显示效果就会变好,如下图所示:

2. 自动化提取一个任意字符的点阵数据
通过windows的画图程序我们能人工提取任何一个字符的点阵数据,但仅仅汉字就高达六七万个,要完成点阵数据的提取人力投入极大,虽然通过windows画图程序获取字符的点阵数据方法不可取,但是获取点阵数据的流程是是可取的,获取点阵数据的流程如下:

借助上面流程流程,结合python提供的相关图形库实现如下:
from PIL import Image, ImageDraw, ImageFont
font_size = 24
my_font = ImageFont.truetype(font="simsun.ttc",size=font_size-1)#可选择其它字体
mono_img = Image.new('1', (font_size, font_size), 255)
draw_img = ImageDraw.Draw(mono_img)
draw_img.text((0,0),chr(ord('老')),font=my_font,fill=0)
pixel = mono_img.load()
#mono_img.show()
#点阵字数据显示
for h in range(font_size):
for w in range(font_size):
if pixel[w, h] > 200:
print("□", end="")
else:
print("■", end="")
print("")

使用上面示例中可对任意一个字符进行的点阵数据进行提取,若需要生成一个所需数量的点阵字库,还存在一些工程问题需要处理:如组织管理点阵数据?如何通过编码查询到所对应的字符点阵数据?等等。
3. 矢量字体参考
windows已安装字体:C:\Windows\Fonts
小米开源免费字体-MiSans:MiSans
开源思源字体:GitHub - adobe-fonts/source-han-sans: Source Han Sans | 思源黑体 | 思源黑體 | 思源黑體 香港 | 源ノ角ゴシック | 본고딕
4. 缺点
由于使用了矢量字体直接转换成点阵方案,对于点阵字号较小(小于16)且笔画较多字体显示可能不好,这时候就需要使用一些特殊的矢量字体,实测windows下的宋体在这种情况小表现较好。