从TrueType字体(TTF)中导出字符(字形)位图

8
我有一个自定义的TrueType字体(TTF),由一堆图标组成,我想将它们渲染为单独的位图(GIF、PNG或其他格式)以供Web使用。你可能认为这是一项简单的任务,但显然并非如此?这里有大量与TTF相关的软件:

http://cg.scs.carleton.ca/~luc/ttsoftware.html

但这些都是不完全符合我的要求的,存在着链接失效和/或难以在现代Ubuntu环境下编译的问题--例如dumpglyphs(C++)和ttfgif(C)由于缺少模糊的依赖项而无法编译。有什么想法吗?

5个回答

12

尝试使用PILImageDrawImageFont模块。

代码应该是这样的:

import Image, ImageFont, ImageDraw

im = Image.new("RGB", (800, 600))

draw = ImageDraw.Draw(im)

# use a truetype font
font = ImageFont.truetype("path/to/font/Arial.ttf", 30)

draw.text((0, 0), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", font=font)

# remove unneccessory whitespaces if needed
im=im.crop(im.getbbox())

# write into file
im.save("img.png")

谢谢!这个很好用,我稍微修改了一下并作为另一个答案添加了进去。 - lambshaanxy

6

以下是更为简洁、更可靠的版本,相较于其他答案(在我看来会裁剪某些字形的部分):

import string

from PIL import Image, ImageFont


point_size = 16
font = ImageFont.truetype("font.ttf", point_size)

for char in string.lowercase:
    im = Image.Image()._new(font.getmask(char))
    im.save(char + ".bmp")

我很想知道是否有更好的方法来构建一个PIL图像,从font.getmask()返回的ImagingCore对象中。


请注意,这将创建 .bmp 图像(这就是我需要的),但是 PIL 的图像转换方法可以用于获取其他图像格式。 - jbg
ImageFont.truetype()的第二个参数应该是以像素为单位的大小,而不是点数(参考链接)。因此,变量point_size应该被重新命名。 - root

4
这是S.Mark答案的一个可行实现,可以将字符'a'到'z'以黑色输出到正确大小的PNG中:
import Image, ImageFont, ImageDraw

# use a truetype font
font = ImageFont.truetype("font.ttf", 16)
im = Image.new("RGBA", (16, 16))
draw = ImageDraw.Draw(im)

for code in range(ord('a'), ord('z') + 1):
  w, h = draw.textsize(chr(code), font=font)
  im = Image.new("RGBA", (w, h))
  draw = ImageDraw.Draw(im)
  draw.text((-2, 0), chr(code), font=font, fill="#000000")
  im.save(chr(code) + ".png")

2

Python3

这是对S.Mark答案的完整实现,但添加了一些注释、变量和字体文件及字符的示例。我尽可能地描述清楚,但你可以简化它以使其按照你的需求工作。

要求:PIL(Pillow)

PILImageDrawImageFont模块。

# pip install Pillow
from PIL import Image, ImageFont, ImageDraw

# use a truetype font (.ttf)
# font file from fonts.google.com (https://fonts.google.com/specimen/Courier+Prime?query=courier)
font_path = "fonts/Courier Prime/"
font_name = "CourierPrime-Regular.ttf"
out_path = font_path

font_size = 16 # px
font_color = "#000000" # HEX Black

# Create Font using PIL
font = ImageFont.truetype(font_path+font_name, font_size)

# Copy Desired Characters from Google Fonts Page and Paste into variable
desired_characters = "ABCČĆDĐEFGHIJKLMNOPQRSŠTUVWXYZŽabcčćdđefghijklmnopqrsštuvwxyzž1234567890‘?’“!”(%)[#]{@}/&\<-+÷×=>®©$€£¥¢:;,.*"

# Loop through the characters needed and save to desired location
for character in desired_characters:
    
    # Get text size of character
    width, height = font.getsize(character)
    
    # Create PNG Image with that size
    img = Image.new("RGBA", (width, height))
    draw = ImageDraw.Draw(img)
    
    # Draw the character
    draw.text((-2, 0), str(character), font=font, fill=font_color)
    
    # Save the character as png
    try:
        img.save(out_path + str(ord(character)) + ".png")
    except:

        print(f"[-] Couldn't Save:\t{character}")

-1
使用像 Gimp 这样的图像软件来显示你感兴趣的所有字符,然后将每个字符保存到一个文件中。虽然不快速和高效,但你知道你会得到什么。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接