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

152 pdf fonts truetype ghostscript embedded-fonts

我知道pdftk.exe可以指示PDF使用哪些字体的实用程序,以及它们是否嵌入.

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

Kur*_*fle 382

你有几个选择.所有这些方法都适用于Linux以及Windows或Mac OS X.但是,请注意,大多数PDF在嵌入字体时不包括完整,完整的字体.大多数情况下,它们只包含文档中使用的字形子集.


运用 pdftops

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

  1. 将PDF转换为PostScript,例如使用XPDF pdftops(在Windows上:pdftops.exe帮助程序).
  2. 现在字体将以.pfa(PostScript)格式嵌入+您可以使用文本编辑器提取它们.
  3. 您可能需要转换.pfa(ASCII)的.pfb使用(二进制)文件t1utilspfa2pfb.
  4. 在PDF文件从未有.pfm.afm文件(字体度量文件)嵌入(因为PDF阅读器对这些内部知识).没有这些,字体文件几乎不能以视觉上令人愉悦的方式使用.

运用 fontforge

另一种方法是使用Free字体编辑器FontForge:

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

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


运用 mupdf

接下来,MuPDF.此应用程序附带一个名为pdfextract(在Windows上pdfextract.exe)的实用程序,可以从PDF中提取字体和图像.(如果您不了解MuPDF,它仍然是相对未知和新的:"MuPDF是一个免费的轻量级PDF查看器和工具包,用便携式C编写.",由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)
Run Code Online (Sandbox Code Playgroud)

此命令将从引用到当前目录的pdf文件中转储所有可提取文件.通常,您会看到各种文件:图像和字体.这些包括PNG,TTF,CFF,CID等.如果图像的PDF对象编号为412,图像名称将类似于img-0412.png.字体名称将类似于FGETYK + LinLibertineI-0966.ttf,如果字体是PDF对象编号为966.

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

再次:请注意,大多数这些字体文件可能只有一个字符子集,可能不代表完整的字体.

更新:(2013年7月)最近的版本mupdf已经看到他们的二进制文件的内部重新洗牌和重命名,不仅仅是一次,而是几次.主要的实用程序曾经是一个"瑞士刀" - 类似的二进制文件mubusy(名称灵感来自busybox?),最近被重命名为mutool.这些支持子命令info,clean,extract,postershow.不幸的是,这些工具的官方文档还不是最新的.如果你在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)
Run Code Online (Sandbox Code Playgroud)

下载地址: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"
Run Code Online (Sandbox Code Playgroud)

或者在Linux,Unix或Mac OS X上:

gs                          \
  -q -dNODISPLAY            \
   /path/to/extractFonts.ps \
  -c "(/path/to/your/PDFFile.pdf) extractFonts quit"
Run Code Online (Sandbox Code Playgroud)

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


运用 pdf-parser.py

最后,Didier Stevens的pdf-parser.py:这个可能不太容易使用,因为你需要对内部PDF结构有一些了解.pdf-parser.py是一个Python脚本,它也可以做很多其他事情.它还可以从对象中解压缩和提取任意流,因此它也可以提取嵌入的字体文件.

但你需要知道要寻找什么.让我们看一个例子吧.我有一个名为big.pdf的文件.作为第一步,我使用-s参数搜索PDF以查找关键字FontFile的任何出现(pdf-parser.py不需要区分大小写的搜索):

pdf-parser.py -s fontfile big.pdf
Run Code Online (Sandbox Code Playgroud)

就我而言,对于我的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
  >>   
Run Code Online (Sandbox Code Playgroud)

它告诉我FontFile2PDF 中有两个实例,这些实例都是PDF对象.15而没有.分别为16.对象号 15持有/FontFile2for font / ArialMT,对象号.16持有/FontFile2for font / Arial-BoldMT.

为了更清楚地表明这一点:

pdf-parser.py -s fontfile big1.pdf | grep -i fontfile
  /FontFile2 15 0 R
  /FontFile2 16 0 R
Run Code Online (Sandbox Code Playgroud)

快速查看PDF规范会发现该关键字/FontFile2"包含TrueType字体程序的流"有关(/FontFile"包含类型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
   >>
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

ls -l dumped-data.ext
  -rw-r--r--  1 kurtpfeifle  staff  1581435 Apr 11 00:29 dumped-data.ext
Run Code Online (Sandbox Code Playgroud)

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

使用类似的字体阅读工具打开文件otfinfo(这是lcdf-typetools的一部分)将导致一些失望:

otfinfo -i dumped-data.ext
  otfinfo: dumped-data.ext: not an OpenType font (bad magic number)
Run Code Online (Sandbox Code Playgroud)

好吧,这是因为我们还没有(pdf-parser.py充分)利用它的全部魔力:转储过滤后的解码流.为此,我们必须添加-f参数:

pdf-parser.py -o 15 -f -d dumped-data-decoded.ext big1.pdf
Run Code Online (Sandbox Code Playgroud)

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

ls -l dumped-data-decoded.ext
  -rw-r--r--  1 kurtpfeifle  staff  778552 Apr 11 00:39 dumped-data-decoded.ext
Run Code Online (Sandbox Code Playgroud)

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

file是什么意思?

file dumped-data-decoded.ext
  dumped-data-decoded.ext: TrueType font data
Run Code Online (Sandbox Code Playgroud)

这是什么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
Run Code Online (Sandbox Code Playgroud)

所以Bingo!,我们有一个胜利者:pdf-parser.py确实为我们提取了有效的字体文件.鉴于此文件的大小(778.552字节),看起来这个字体甚至完全嵌入PDF中...

我们可以将它重命名为arial-regular.ttf并安装它,并愉快地使用它.


注意事项:

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

  • 大多数PDF文件都没有嵌入完整的字体,但只有子集.提取字体的子集仅在非常有限的范围内有用(如果有的话).

请阅读以下有关字体提取工作的优点和(更多)缺点:

  • 很好的答案!这值得再多投票 (12认同)
  • @ kizzx2:随意投票或下注任何其他[PDF]或[Ghostscript]答案:-) (3认同)

igo*_*igo 25

使用在线服务http://www.extractpdf.com.无需安装任何东西.

  • 就我而言,它只能提取 Type 1 字体,不能提取 TrueType (2认同)

Guy*_*der 7

尽管这个问题已有 10 年历史,但它仍然有效,并且随着技术的变化,有效的答案也在变化。

在搜索当前答案时,没有人注意到 WOFF(Web 开放字体格式)(W3C)(维基百科),它可用于重新创建单个字符(字形)并将它们准确地显示在网页中。

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

WOFF 文件可以在WOFFer 上与 OTF 或 TTF相互转换——WOFF字体转换器

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

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

PS,当我了解更多关于使用 woff 文件类型的信息时,我可能会更新更多信息,但由于这是知识共享,如果您有一些有价值的东西可以传递,请随时编辑此答案。

  • 谢谢你!这个解决方案对我有用(如创建有效的 TTF),而我尝试过的其他解决方案则不然。是因为 WOFF 能更好地处理不完整的字体吗? (2认同)

小智 6

最终找到FontForge Windows安装程序包并通过已安装的程序打开PDF.工作了一个享受,很开心.