尝试将所有TTF字形转换为PNG


以前,我在另一篇文章中总结了与ASCII艺术相关的论文
我搜索了与ASCII艺术相关的论文

其中,有一篇文章我在" ASCII艺术分类方法的比较"中进行了各种搜索,以"提取每个字符的图像特征(HOG)..."。在本文中,我将ttf文件输出为png。最终目标是通过机器学习对AA进行分类。

本文介绍的方法是按照以下步骤将ttf转换为png。

  • 使用fonttools读取ttf文件中的字形列表
  • 使用SVGPathPen将所有字形转换为SVG
  • 使用cairosvg将SVG转换为PNG
  • 调整大小和缩小PNG *可能不需要...
  • 如果您有兴趣,请阅读以下步骤。另外,关于1和2的内容,请参阅以下博客。它写得非常详细,因此,如果您不知道fonttools,请阅读它。
    使用fontTools笔

    获取字形轮廓

    *以下过程假定您正在使用jupyter笔记本。

    1.使用fonttools读取ttf文件

    的字形列表

    首先,使用fonttools在Python中处理ttf文件。安装方法来自pip

    1
    pip install fonttools

    执行以下过程以使用fonttools读取字体并获取字形。

    1
    2
    3
    4
    from fontTools.ttLib import TTFont
    font = TTFont('/Users/eskey/workspace/aahub/ml/Saitamaar.ttf')
    glyph_set = font.getGlyphSet()
    cmap = font.getBestCmap()

    glyph_set是字形对象,而cmap是Unicode和字形对应表。

    2.使用SVGPathPen

    将所有字形转换为SVG

    现在,字形信息已准备就绪,请将其转换为SVG。首先,为文件输出创建目录。

    1
    2
    3
    4
    import os
    os.mkdir("output_svg")
    os.mkdir("output_png")
    os.mkdir("output_resize")

    接下来,编写一个将所有字形转换为SVG的函数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    from textwrap import dedent
    from fontTools.pens.svgPathPen import SVGPathPen

    # GlyphをSVGに変換
    def save_all_glyph_as_svg(font):    
        glyph_set = font.getGlyphSet()
        cmap = font.getBestCmap()

        output_path = "output_svg/"
        for c in cmap:
            glyph_name = cmap[c]
            glyph = glyph_set[glyph_name]
            svg_path_pen = SVGPathPen(glyph_set)
            glyph.draw(svg_path_pen)

            ascender = font['OS/2'].sTypoAscender
            descender = font['OS/2'].sTypoDescender
            width = glyph.width
            height = ascender - descender

            content = dedent(f'''\
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 {-ascender} {width} {height}">
                    <g transform="scale(1, -1)">
                        <path d="{svg_path_pen.getCommands()}"/>
                    </g>
                </svg>
            ''')
            with open(output_path + str(c) + ".svg", 'w') as f:
                f.write(content)

    上面的函数是循环cmap表并将所有字形另存为SVG的函数。

    1
    save_all_glyph_as_svg(font)

    运行

    时,SVG将保存在output_svg文件夹中。
    Screen Shot 2018-12-31 at 20.42.31.png

    3.使用cairosvg

    将SVG转换为PNG

    将所有字形另存为SVG之后,下一步是将它们转换为PNG。 cariosvg也可以通过pip安装。

    1
    pip install cairosvg

    顺便说一句,cariosvg具有一个称为svg2png的功能,可将SVG转换为PNG。

    1
    svg2png(url="SVGのパス", write_to="出力先のパス")

    创建一个函数,将output_svg的所有SVG转换为PNG。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    from cairosvg import svg2png
    import os


    # SVGをPNGに変換する
    def convert_all_svg_to_png():
        path = "output_svg"
        files = os.listdir(path)
        files_file = [f for f in files if os.path.isfile(os.path.join(path, f))]
        for fname in files_file:
            bname, ext =  os.path.splitext(fname)

            try:
                svg2png(url='output_svg/' + bname + '.svg', write_to='output_png/' + bname + '.png')
            except:
                print(fname)
        return

    在上述过程中,svg2png异常处理由try?除外。这是因为svg2png使用零宽度空间Unicode崩溃。以下是似乎属于svg2png的代码。
    uni200B
    uniE9D7
    uniE9D6
    uniE9D5
    uni035F
    uni035D
    uni035E
    uni0009

    执行该功能。

    1
    convert_all_svg_to_png()

    棒极了,SVG已转换为PNG。
    Screen Shot 2018-12-31 at 20.42.40.png

  • 调整大小和缩小PNG
    通过上述处理已经实现了将ttf转换为png的目的,但是在这种状态下尺寸非常大。
  • 根据情况可能需要调整图像尺寸,因此请记下以下处理。以下功能将output_png文件夹中所有图像文件的大小调整为20/1。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import os
    import glob
    from PIL import Image


    # PNGをリサイズする
    path = "output_png"
    files = os.listdir(path)
    files_file = [f for f in files if os.path.isfile(os.path.join(path, f))]
    for fname in files_file:
        bname, ext =  os.path.splitext(fname)
        if ext != ".png":
            continue
        img = Image.open("./output_png/" + bname + ext)
        img_resize = img.resize((int(img.width/20), int(img.height/20)))
        img_resize.save("./output_resize/" + bname + "_herf" + ext)

    现在您可以将所有文本文件转换为大小为1/20的图像。此后,我想提取HOG并将其聚类,并使其能够从AA中很好地在HOG中表达。
    好吧。