Skip to content

Instantly share code, notes, and snippets.

@celestialphineas
Created January 22, 2021 06:14
Show Gist options
  • Save celestialphineas/9bce1ddf5ca83b46e9ed187895fd0be7 to your computer and use it in GitHub Desktop.
Save celestialphineas/9bce1ddf5ca83b46e9ed187895fd0be7 to your computer and use it in GitHub Desktop.
从字体文件输出字形
import os
import numpy as np
# 需要Pillow库
from PIL import Image, ImageDraw, ImageFont
# 需要fonttools库
from fontTools.ttLib import TTFont
# 从字体中返回一个字的图像(以numpy数组形式储存)
# 对大多数符合规范的字体,这个函数可以保证输出图像的边框正好是汉字的字身框
#(相当于稿纸上面的格子。一般比bounding box大一点,汉字在设计的时候不是顶着格的)
# 字体可以通过fontname传入,也可以通过img_font和font传入
# fontname传入字体文件名,每次调用都会重新打开字体,不推荐
# img_font和font需要同时传入,img_font是一个PIL ImageFont对象,font是一个TTFont对象
# h是输出图像大小,默认1000x1000
# binarize为True时返回二值图(0, 1, np.uint8),为False返回单通道位图(0~255, np.uint8)
def get_glyph_img(hanzi, fontname='', h=1000, binarize=True, img_font=None, font=None):
if img_font is None: img_font = ImageFont.truetype(fontname, h)
if font is None: font = TTFont(fontname)
upm = font['head'].unitsPerEm
typo_ascender = font['OS/2'].sTypoAscender
ascent, _ = img_font.getmetrics()
img = Image.new('L', (h, h), 0)
draw = ImageDraw.Draw(img)
draw.text((0, typo_ascender/upm*h - ascent), hanzi, 255, font=img_font)
img_array = np.array(img, dtype=np.uint8)
if not binarize: return img_array
else: return (img_array > 128).astype(np.uint8)
# 检查字体是否有某个字,有的话返回True
# fontname和font传入其中之一,fontname是字体文件名,font是一个TTFont对象
# 建议传入font。因为传入fontname会反复打开文件,开销大
def has_glyph(char, fontname='', font=None):
if font is None: font = TTFont(fontname)
for table in font['cmap'].tables:
if ord(char) in table.cmap.keys():
return True
return False
# 上面两个函数的使用范例:
# --------
# 字体文件名
project_font = 'dbt.ttf'
size = 1000
font = TTFont(fontname)
# 注意:ImageFont对象要传入字号
img_font = ImageFont.truetype(fontname, size)
img = get_glyph_img('人', h=size, binarize=False, img_font=img_font, font=font)
from skimage import io
io.imshow(img)
io.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment