如何将位图字体(.FON)转换为truetype字体(.TTF)?

时间:2010-09-20 09:29:53

标签: fonts true-type-fonts bitmap-fonts

我的程序(win32,Delphi)需要在表的某些列中显示特殊字符。为此,我为这些列使用了特殊字体。我从我的客户那里得到了字体。它是一个.FON字体。它在屏幕上工作得很好,但是一旦我想用它来打印东西,我就会经常遇到问题。

我想将此.FON字体转换为truetype字体(.TTF)以避免出现问题。我不在乎字体不能很好地扩展。当我在屏幕上使用与原始字体的默认大小相同的大小时,我应该看起来完全相同。 有人知道这样做的方法吗?

(它不需要源代码解决方案。字体不会改变。如果我找到一个工具就足够了)

编辑:理想的是获得一个truetype字体,其中原始字体的每个像素都转换为矢量黑色方块(我通过手动重绘几个字符进行测试,它会按我想要的方式工作)。

编辑2,使用的解决方案:使用FontForge + Autotrace,然后手动进行更正我能够获得一个跟随像素轮廓的矢量字体位图字体。这种矢量字体比原始字体更好地缩放并解决了我的打印问题。有关详细信息,请参阅接受的帖子。

但如果有人知道完全自动化的解决方案,我仍然感兴趣。

11 个答案:

答案 0 :(得分:15)

使用FontForge + Autotrace然后手动进行一些更正。

首先在Fontforge中集成Autotrace,请参阅Autotracing bitmaps in FontForge。我是这样做的,因为我无法使用winF版本的FontForge:

  1. 下载,解压缩并启动Portable Ubuntu Tres。这是一个特殊的Linux版本,可以在Windows下运行!
  2. 选择系统 - >管理 - >添加/删除应用程序,搜索FontForge并进行安装(管理员密码为123456)。我安装了FontForge版本20090622。
  3. http://autotrace.sourceforge.net/index.html#download下载autotrace-0.31.1.tar.gz并将其复制到Portable Ubuntu的主目录中。
  4. 在Portable Ubuntu中选择Applications-> Accessories-> Terminal来编译和安装autotrace:

    sudo bash  (password is 123456)
    gunzip autotrace-0.31.1.tar.gz
    tar xf autotrace-0.31.1.tar
    cd autotrace-0.31.1
    ./configure
    make
    make install
    
  5. 然后转换你的字体:

    1. 在Portable Ubuntu中启动FontForge并打开.FON字体。
    2. 将字体保存为.BDF字体(加载.FON文件作为背景对我不起作用,所以我必须先转换字体):文件 - >生成字体并选择BDF作为格式。
    3. 创建新字体并将BDF字体导入为背景字体:文件 - >导入,不要忘记选择“作为背景”。
    4. 选择所有字符并按住shift键启动自动跟踪,以便输入autotrace的参数。我使用了以下参数,这些参数改进了对像素轮廓的识别,但我没有找到完美的参数:

      -corner-surround=1 -line-threshold=10
      
    5. 主要使用“添加曲线点”功能手动更正字符。 激活视图 - >显示 - >几乎水平/垂直线使工作更容易。
    6. 生成truetype字体:File->生成字体并选择truetype作为格式。

答案 1 :(得分:9)

我知道这个问题已经过时了,但是对于它的价值,我可以使用PixFont轻松地将旧的.fon转换为.ttf。我以管理员的身份运行它(没有安装 - 旧的学校可执行文件)并且它生成了一个好的TTF,即使原始.fon缺少一些正确的字形。

而且,虽然它不是免费的,但它几乎是29美元,特别是与非常昂贵的商业产品相比。

答案 2 :(得分:6)

对于那些不想编译fontforge(对于windows)的人,请在此处下载: http://www.mpetroff.net/software/fontforge-windows/

该构建使用potrace而不是autotrace。我获得的转换字体(vgasys.fon)的最佳参数是:

--turdsize 0 --opttolerance 0 --unit 1 --longcurve --gamma 0 --blacklevel 0 --cleartext

要使字体看起来很好(通过添加和删除点),仍需要数小时的手动工作。

答案 3 :(得分:4)

使用FontForge我能够生成相应的truetype字体,当使用良好的大小时,它会提供与原始字体完全相同的字符。可能我还需要调整一些选项,因为我在size = 11时使用了原始字体。新字体仅在size = 10.5时才有效,这在delphi中是不可能的。其他任何尺寸的字体看起来都非常糟糕。

  1. 在FontForge中加载.FON字体
  2. 选择文件 - >生成字体
  3. 选择“(伪造)MS位图仅sfnt(ttf)”作为类型,输入文件名并单击“保存”。
  4. 显然,它可以使用truetype-font存储位图字体。生成的字体没有我对位图字体的问题,但它在打印机上是完全空白的,因此它无法解决我的问题。

    关于FontForge的说明 我没有设法安装Windows版本的FontForge(基于cygwin)。而不是我安装Portable Ubuntu Tres,这是一个适用于Windows的Linux版本。它易于安装:解压缩文件并启动exe。然后选择System-> Administration-> Add / Remove Applications并搜索FontForge并安装它(管理员密码为123456)。我安装了FontForge版本20090622。

答案 4 :(得分:2)

可能使用命令行工具SBIT32 fom Microsoft。使用FontForge将.FON文件转换为.BDF文件很容易。但是,您需要编写一个度量文件(.MET)。我没有尝试过,因为我想我会得到一个带有嵌入式位图字体的truetype-font,并且可以直接用FontForge生成这样的字体(类型“(伪造的)MS位图只有sfnt(ttf) )“在文件 - >生成字体下”。

答案 5 :(得分:2)

我发现获得一个好的TTF版FON的最简单方法是使用一个免费的在线位图字体编辑器。您必须手动输入每个字形,但该过程比掌握FontForge要简单得多。我知道有两个编辑器,它们都生成在Windows和Linux上运行良好的TTF。

BitFontMaker更简单。我喜欢它干净的界面,但我最终没有使用它,因为等宽字体的单元格宽度只有10到14像素。

FontStruct需要注册并使用Flash界面。一旦习惯了界面,我就可以很快地创建新字体。 (这可能是巧合,但我注意到我用来注册的电子邮件帐户上的垃圾邮件数量有所增加。)

两个编辑器都会自动设置行间距。获得所需间距的技巧是在一个字符上添加一个高像素,然后使用矢量字体编辑器将其从TTF中删除。 ( Type light 效果很好,比FontForge更容易使用。)

答案 6 :(得分:1)

根据产品说明BitFonter 3.0似乎能够做到这一点:

  

通过与FontLab Studio和TypeTool集成,将位图和位图字体强制转换为Type 1,TrueType和OpenType字体。

但转换一种字体只需要999美元。

答案 7 :(得分:1)

您不可能使用简单的免费工具完成它。 http://www.fontlab.com有工具可以做,但它们非常昂贵。

答案 8 :(得分:1)

我发现自己正在搜索这些字体以用于我正在处理的项目。考虑到手动编辑其他答案中提到的所有字形,我继续搜索。最终我偶然发现了一个拥有原始字体的网站以及一些较新的.ttf变体。如果你不关心某些字形已被重新映射(它们都存在),这是一个不错的选择:Oldschool PC Fonts。作为一个额外的奖励,这些支持扩展了拉丁语,希腊语,西里尔语和希伯来语脚本以及一堆额外的字形和Unicode符号。

答案 9 :(得分:0)

我无法使用autotrace工作,因此我编写了一个蟒蛇脚本来将黑白图像跟踪为矢量多边形,每个像素一个。

因此,使用字形图像文件夹,您可以将其转换为svg个文件的文件夹。

然后在Inkscape联合+简化路径来清理每个字形。 (可能在使用Inkscape的命令行上可行)

最后为每个字形将相应的svg导入FontForge。

- >脚本位于gist.gisthub.com

from PIL import Image
import svgwrite
import os
import argparse


def bmp_to_svg(filename, multiply =1):

    img = Image.open(filename)
    w, h = img.size
    pixel_acc = img.load()

    generated_paths = paths_gen(pixel_acc, w,h, multiply=multiply)

    dwg = svgwrite.Drawing(profile='tiny')
    for path in generated_paths:
        options = path
        kwoptions = {} #{"fill":"black"}
        dwg.add(dwg.polygon(options, **kwoptions))

    #clip_path = dwg.defs.add(dwg.clipPath())
    #clip_path.add(dwg.Rect(insert=(0,0), size=((w*multiply)+1, (h*multiply)+1)))
    return dwg

def paths_gen(pixel_acc, w, h, multiply = 1):
    m = multiply
    paths = []
    for y in range(0,h):
        for x in range(0,w):
            pix = pixel_acc[x,y]
            brightval = sum(pix) /3
            if brightval < 128:
                paths.append([
                        ##top left
                        (x * m, y * m),
                        ##top right
                        ((x+1) * m, y * m),
                        ##bottom right
                        ((x+1) * m, (y+1) * m),
                        ##bottom list
                        ((x) * m, (y+1) * m),
                        ##close back to top left
                        #(x, y), 
                    ])
    return paths


def main():
    parser = argparse.ArgumentParser(
        description='Script to convert black and white images into vector art')
    parser.add_argument("input_dir")
    parser.add_argument("ouput_dir")
    parser.add_argument("in_ext", default="bmp", help="file extension of images in input folder")
    parser.add_argument("-m", "--multiply", default=1, type=int)
    ## TODO
    #parser.add_argument("-u", "--union", store=True, help="unifies adjecent polgons")
    #parser.add_argument("-s", "--simplify", store=True, help="removes points that are part of a straight line")
    #parser.add_argument("-c", "--compress", store=True, help="same as '--union --simplify'")

    args = parser.parse_args()


    cdir = os.path.abspath(args.input_dir)

    fn_gen = ( x for x in os.listdir(cdir)
                 if x.endswith('.'+args.in_ext)
             )

    for count, filename in enumerate(fn_gen):

        full_filename =  os.path.join(cdir, filename)

        new_fn = "{}_.svg".format(filename)
        new_fullfn =  os.path.join(args.ouput_dir, new_fn)


        svg = bmp_to_svg(full_filename, multiply=args.multiply)
        print "Converted file: '{}'".format(full_filename)
        svg.filename = new_fullfn
        svg.save()

if __name__ == '__main__':
    main()

答案 10 :(得分:0)

我不得不经历很多麻烦才能找到适合我的解决方案。

如果按比例缩放输入,自动跟踪似乎会产生像素完美的输出,根据我的经验,缩放至少8倍是完美的。

由于关闭了软件,缩放输入的过程过于复杂。

Bitfonter可以打开bdf字体(确实支持Unicode)并且可以缩放。演示版本的问题在于,在导出时有一半的字形被“破坏”(像素被随机删除),这使Autotrace再次产生了不良的输出。但是,我注意到有一种字符“损坏”的模式:第一和第二字形已损坏,第三和第四字形未损坏,第五和第六字形已损坏,依此类推。因此,我通过再次缩放它来制作了互补的bdf文件,但随后删除了前两个字形。然后,可以在FontForge中完成两者的合并:打开两个输出文件,在“编码”中将“重新编码”转换为“字形顺序”,在output2中选择所有内容并复制,在output1中单击第三个字形,然后按Ctrl + Shift + V.这将合并两个输出文件,并使所有字符的缩放比例完美无误,除了前两个字形可以手动完成。保存结果。

在此缩放的输出上执行“自动跟踪”。然后,在所有字形的Element \ Transformations \ Transform上,然后使用以下设置:原点:字形原点,均匀缩放...之前缩放bdf的倒数(如果是8x缩放,即12.5%)。

有更多的点超出需要,可以使用Element \ Simplify \ Simplify来解决,这将简化轮廓。在这种仅由水平和垂直线构成轮廓的特定情况下,此操作应无损。

然后,在所有这些之后,我注意到这些字形似乎没有Unicode信息。打开具有最终字体确切字符的任何字体,对该字体使用Encoding \ Reencode \ ISO 10646-1(Unicode,BMP),然后使用Compact。然后将所有具有正确轮廓的字体中的所有字符复制到具有所有正确Unicode编码的字体上。

如果您无法按照步骤进行操作,请告诉我发生了什么事。这确实太复杂了,尝试使用和组合我能找到的每个工具的效果都非常麻烦,但是我找到了解决方案。它是自动的,与带有大量字符的字体相比,重新绘制所有字符更容易。这对于绘制位图字形并具有有效位图字体文件但仍无法使用的人来说将是有帮助的。