如何从PDF中提取嵌入字体作为有效字体文件?


161

我知道该pdftk.exe实用程序可以指示PDF使用了哪些字体,以及是否嵌入了这些字体。

现在的问题是:假设我有带有嵌入字体的PDF文件-如何提取这些字体以使其可重新用作常规字体文件?是否有(最好是免费的)工具可以做到这一点?另外:可以使用iText以编程方式完成此操作吗?

Answers:


405

您有几种选择。所有这些方法都可以在Linux以及Windows或Mac OS X上使用。但是,请注意,大多数PDF嵌入字体后,都不会包含完整的完整字体。通常,它们仅包括文档中使用的字形的子集


使用 pdftops

在* nix系统上执行此操作的最常用方法之一包括以下步骤:

  1. 例如,通过使用XPDF pdftops(在Windows上为pdftops.exe帮助程序)将PDF转换为PostScript 。
  2. 现在,字体将以.pfa(PostScript)格式嵌入,并且您可以使用文本编辑器提取它们。
  3. 您可能需要转换.pfa(ASCII)的.pfb使用(二进制)文件t1utilspfa2pfb
  4. 在PDF中,从不嵌入.pfm.afm嵌入文件(字体规格文件)(因为PDF查看器对此具有内部了解)。没有这些,字体文件就很难以令人愉悦的方式使用。

使用 fontforge

另一种方法是使用免费字体编辑器FontForge

  1. 使用打开文件时使用的“打开字体”对话框。
  2. 然后在对话框的过滤器部分中选择“从PDF提取”
  3. 选择要提取字体的PDF文件。
  4. 将打开“选择字体”对话框-在此处选择要打开的字体。

查看FontForge手册。为了将提取的字体数据保存为可重复使用的文件,您可能需要遵循一些不一定很简单的特定步骤。


使用 mupdf

接下来,MuPDF。该应用程序带有一个称为pdfextract(在Windows上pdfextract.exe)的实用程序,该实用程序可以从PDF中提取字体和图像。(以防您不了解MuPDF,而它仍然是一个相对未知的新事物:“ MuPDF是用便携式C编写的免费轻量级PDF查看器和工具包。”,由Artifex软件开发人员编写,该公司也是为我们提供Ghostscript的公司。 )
更新: MuPDF的较新版本已将“ pdfextract”的先前功能移至“ mutool extract”命令。在此处下载:mupdf.com/downloads

注意:pdfextract.exe是一个命令行程序。要使用它,请执行以下操作:

c:\>  pdfextract.exe  c:\path\to\filename.pdf         # (on Windows)
$>    pdfextract  /path/tofilename.pdf                # (on Linux, Unix, Mac OS X)

此命令将从参考的pdf文件中提取所有可解压缩的文件到当前目录中。通常,您会看到各种文件:图像和字体。这些措施包括PNG,TTF,CFF,CID等形象的名字会像IMG-0412.png如果图像的PDF对象人数为412 fontnames会像FGETYK + LinLibertineI-0966.ttf,如果字体的PDF对象编号为966。

CFF(压缩字体格式)文件是一种公认​​的格式,可以通过各种转换器将其转换为其他格式,以用于不同的操作系统。

再次:请注意,这些字体文件中的大多数可能只包含一个字符子集,并且可能不代表完整的字体。

更新:(2013年7月)的最新版本mupdf已经对内部二进制文件进行了内部改组和重命名,不仅一次,而且多次。主要实用程序曾经是类似“瑞士刀”的二进制文件,名为mubusy(受busybox启发吗?),最近更名为mutool。这些支持子命令infocleanextractpostershow。不幸的是,这些工具的官方文档尚未更新。如果您在Mac上使用“ MacPorts”:则该实用程序已重命名,以避免与使用相同名称的其他实用程序发生名称冲突,您可能需要使用mupdfextract

要使用mutool以前的工具获得(大致)等效的结果pdfextract,只需运行mubusy extract ...。*

因此,要提取字体和图像,您可能需要运行以下命令行之一:

c:\>  mutool.exe extract filename.pdf      # (on Windows)
$>    mutool     extract filename.pdf      # (on Linux, Unix, Mac OS X)

下载在这里:mupdf.com/downloads


使用gs(Ghostscript)

然后,Ghostscript也可以直接从PDF中提取字体。但是,它需要使用extractFonts.psPostScript语言编写的名为的特殊实用程序的帮助,可以从Ghostscript源代码存储库中获得该实用程序。

现在使用它,您需要同时运行此文件extractFonts.ps和PDF文件。然后,Ghostscript将使用PostScript程序中的指令从PDF中提取字体。在Windows上看起来像这样(是的,Ghostscript理解'正斜杠',/,在Windows上也作为路径分隔符!):

gswin32c.exe                  ^
  -q -dNODISPLAY              ^
   c:/path/to/extractFonts.ps ^
  -c "(c:/path/to/your/PDFFile.pdf) extractFonts quit"

或在Linux,Unix或Mac OS X上:

gs                          \
  -q -dNODISPLAY            \
   /path/to/extractFonts.ps \
  -c "(/path/to/your/PDFFile.pdf) extractFonts quit"

几年前,我已经测试了Ghostscript方法。当时它确实提取* .ttf(TrueType)很好。我不知道是否还会提取其他字体类型,如果可以的话,是否可以重复使用。我不知道该实用程序是否会阻止提取标记为受保护的字体。


使用 pdf-parser.py

最后,迪迪埃·史蒂文斯(Didier Stevens)的pdf-parser.py:该代码可能不太容易使用,因为您需要掌握有关内部PDF结构的一些专门知识。pdf-parser.py是一个Python脚本,它也可以做很多其他事情。它还可以解压缩并从对象提取任意流,因此也可以提取嵌入的字体文件。

但是您需要知道要寻找什么。让我们看一个例子。我有一个名为big.pdf的文件。第一步,我使用-s参数在PDF中搜索是否出现关键字FontFilepdf-parser.py不需要区分大小写的搜索):

pdf-parser.py -s fontfile big.pdf

就我而言,对于big1.pdf,我得到以下结果:

obj 9 0
 Type: /FontDescriptor
 Referencing: 15 0 R
  <<   
    /Ascent 728
    /CapHeight 716
    /Descent -210 
    /Flags 32
    /FontBBox [ -665 -325 2000 1006 ]
    /FontFile2 15 0 R
    /FontName /ArialMT
    /ItalicAngle 0
    /StemV 87
    /Type /FontDescriptor
    /XHeight 519
  >>   

obj 11 0 
 Type: /FontDescriptor
 Referencing: 16 0 R
  <<   
    /Ascent 728
    /CapHeight 716
    /Descent -210 
    /Flags 262176
    /FontBBox [ -628 -376 2000 1018 ]
    /FontFile2 16 0 R
    /FontName /Arial-BoldMT
    /ItalicAngle 0
    /StemV 165
    /Type /FontDescriptor
    /XHeight 519
  >>   

它告诉我FontFile2PDF内有两个实例,这些实例在PDF对象中没有。15,没有。16。对象编号 15拥有/FontFile2for字体/ ArialMT,对象号。16拥有/FontFile2for字体/ Arial-BoldMT

为了更清楚地显示这一点:

pdf-parser.py -s fontfile big1.pdf | grep -i fontfile
  /FontFile2 15 0 R
  /FontFile2 16 0 R

快速浏览一下PDF规范,您会发现该关键字/FontFile2“包含TrueType字体程序的流”相关/FontFile将与“包含Type 1字体程序的流/FontFile3相关,并且与“格式为由流字典中的子类型条目指定( {因此是Type1CCIDFontType0C子类型}。)

要专门查看PDF对象编号。15(拥有字体/ ArialMT),可以使用以下-o 15参数:

pdf-parser.py -o 15 big1.pdf

 obj 15 0
  Type: 
  Referencing: 
  Contains stream
   <<
     /Length1 778552
     /Length 1581435
     /Filter /ASCIIHexDecode
   >>

pdf-parser.py输出告诉我们,该对象包含一个长度为1.581.435字节的流(它将不会直接显示),并且使用ASCIIHexEncode进行了编码(==“压缩”),并且需要进行解码(==“ de-压缩”或“已过滤”)/ASCIIHexDecode

要转储来自对象的任何流,pdf-parser.py可以使用-d dumpname参数调用。我们开始做吧:

pdf-parser.py -o 15 -d dumped-data.ext big1.pdf

我们提取的数据转储将位于名为dumped-data.ext的文件中。让我们看看它有多大:

ls -l dumped-data.ext
  -rw-r--r--  1 kurtpfeifle  staff  1581435 Apr 11 00:29 dumped-data.ext

哦,看,它是1.581.435字节。我们在上一个命令的输出中看到了该图。使用文本编辑器打开此文件,确认其内容为ASCII十六进制编码的数据。

首先使用诸如此类的字体读取工具打开文件otfinfo(这是lcdf-typetools软件包的一部分),这会导致一些失望:

otfinfo -i dumped-data.ext
  otfinfo: dumped-data.ext: not an OpenType font (bad magic number)

好的,这是因为我们(尚未)pdf-parser.py充分利用其全部魔力:转储经过过滤,解码的流。为此,我们必须添加-f参数:

pdf-parser.py -o 15 -f -d dumped-data-decoded.ext big1.pdf

这个新文件的大小是多少?

ls -l dumped-data-decoded.ext
  -rw-r--r--  1 kurtpfeifle  staff  778552 Apr 11 00:39 dumped-data-decoded.ext

哦,看:确切的数字也已经存储在PDF对象编号中。15字典作为键的值/Length1...

是什么file觉得它是什么?

file dumped-data-decoded.ext
  dumped-data-decoded.ext: TrueType font data

otfinfo告诉我们什么?

otfinfo -i dumped-data-decoded.ext
  Family:              Arial
  Subfamily:           Regular
  Full name:           Arial
  PostScript name:     ArialMT
  Version:             Version 5.10
  Unique ID:           Monotype:Arial Regular:Version 5.10 (Microsoft)
  Designer:            Monotype Type Drawing Office - Robin Nicholas, Patricia Saunders 1982
  Manufacturer:        The Monotype Corporation
  Trademark:           Arial is a trademark of The Monotype Corporation.
  Copyright:           © 2011 The Monotype Corporation. All Rights Reserved.
  License Description: You may use this font to display and print content as permitted by
                       the license terms for the product in which this font is included.
                       You may only (i) embed this font in content as permitted by the 
                       embedding restrictions included in this font; and (ii) temporarily 
                       download this font to a printer or other output device to help
                       print content.
  Vendor ID:           TMC

因此,Bingo!是我们的赢家:pdf-parser.py确实为我们提取了有效的字体文件。给定此文件的大小(778.552字节),看起来该字体甚至完全嵌入了PDF ...

我们可以将其重命名为arial-regular.ttf并按原样安装并愉快地使用它。


注意事项:

  • 无论如何,您都需要遵循适用于该字体的许可证。某些字体许可证不允许免费使用和/或分发。盗版字体就像盗版任何软件或其他受版权保护的材料一样。

  • 无论如何,大多数原始的PDF都不会嵌入完整字体,而只是嵌入子集。提取字体的子集仅在非常有限的范围内有用(如果有的话)。

还请阅读以下有关字体提取方面的优点和(更多)缺点的内容:


3
@ kizzx2:随时可以投票或降级我的其他[PDF]或[Ghostscript]答案:-)
Kurt Pfeifle

如果您在Mac上并从端口(或也可能从二进制文件)安装mupdf,则解压缩也称为mupdfextract。您可以从终端运行它,只要它在路径中即可。
Orwellophile 2012年

@Orwellophile:感谢您的提示。我以此为契机,更新了有关的一些提示mupdf。又见 ...
库尔特Pfeifle

我会检查出来的。就是这样,这并不是没有意义的评论:您的过程非常好...(投票)...它提取并命名了字体的3个变体,然后我使用fontforge(也从macports中删除了)进行合并。不幸的是,我的字体仍然缺少大写字母“ X” ...的几率是:p
Orwellophile 2012年

1
@Chris:是的,这是两个不同的子集(甚至可能在很大的一部分上重叠)。没有自动合并它们的选项。
Kurt Pfeifle




3

即使这个问题已有10年的历史了,它仍然是有效的,并且随着技术的发展,有效的答案也随之而来。

在搜索当前答案时,没有发现任何注意事项,请注意WOFF(Web开放字体格式)(W3C)(维基百科),可用于重新创建单个字符(字形)并将其准确显示在网页中。

使用IDR Solutions提供的免费在线网页,将PDF转换为HTML5(链接),将PDF转换为zip文件。在生成的zip中将是woff文件类型的字体目录。如果您不知道,当前的Internet浏览器支持woff文件。(参考)可以在在线网站FontDrop上检查这些内容!(链接)。

WOFF文件可以在WOFFer – WOFF字体转换器与OTF或TTF之间进行转换。

另外,从PDF到HTML5的zip文件还将包含可在Internet浏览器中打开的PDF每页的HTML文件,这是我发现或看到的最好,最准确的PDF译文之一。

虽然我只是在学习如何使用WOFF文件,但这是值得传递的。请享用。

附言:随着我了解有关使用woff文件类型的更多信息,我可能会提供更多信息,但是由于这是创用CC,如果您有有价值的建议可以随时编辑此答案。


谢谢!此解决方案对我有效(如创建有效的TTF),而我尝试过的其他解决方案则不行。是因为WOFF可以更好地处理不完整的字体吗?
大安

@Daan Is it because WOFF handles incomplete fonts better?我不知道。您的猜测将是我的一个好选择。正如我指出的,我自己只是在学习WOFF。
Guy Coder

@Daan也许您应该将其发布Is it because WOFF handles incomplete fonts better?为新的SO问题,其他具有更多知识的人将会看到并希望提供有意义的答案。
Guy Coder

我可能会那样做。谢谢。
大安

2

PDFTron的PDF2SVG 6.0版做得很合理。.otf默认情况下,它会生成OpenType()字体。使用--preserve_fontnames保留“从源文件中获取字体/ FONT-FAMILY命名方案。”

PDF2SVG是一种商业产品,但是您可以下载免费的演示可执行文件(该文件在SVG输出上包含水印,但没有其他限制)。可能还有其他PDFTron产品也可以提取字体,但我直到最近才发现PDF2SVG。


不幸的是--preserve_fontnames,如果您重叠的部分字体不起作用-它似乎不包含前缀,例如MSCIYGin MSCIYG+Ge'ez-1,因此会覆盖之前的部分字体。
克里斯


0

这是@Kurt Pfeifle的答案font-forge部分的后续内容,该部分专门针对Red Hat(以及其他Linux发行版)。

  1. 打开PDF并选择所需的字体后,将需要选择“文件->生成字体...”选项。
  2. 如果文件中有错误,则可以选择忽略它们或保存文件并进行编辑。如果单击“修复”足够的次数,大多数错误可以自动修复。
  3. 单击“元素->字体信息...”,然后将“字体名称”,“家族名称”和“人类名称”设置为所需的值。如果不是,请修改它们并将文件保存在某处。这些名称将确定字体在系统上的显示方式。
  4. 选择您的文件名,然后单击“保存...”

拥有TTF文件后,您可以通过以下方式将其安装在系统上

  1. 将其复制到文件夹/usr/share/fonts(作为根用户)
  2. 运行fc-cache -f /usr/share/fonts/(以root用户身份)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.