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

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

现在的问题是: 既然我已经有了带有嵌入字体的 PDF 文件——我怎样才能以一种可以作为常规字体文件重复使用的方式提取这些字体呢?是否有(最好是免费的)工具可以做到这一点?还有: 这是否可以通过编程方式完成,比如说,iText?

332070 次浏览

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


使用 pdftops

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

  1. 例如,使用 XPDF 的 强 > pdftops(在 Windows 上: pdftops.exe辅助程序)将 PDF 转换为 PostScript。
  2. 现在字体将嵌入在 .pfa(PostScript)格式 + 你可以提取他们使用 文本编辑器
  3. 您可能需要使用 t1utilspfa2pfb.pfa(ASCII)转换为 .pfb(二进制)文件。
  4. 在 PDF 文件中从来没有 .pfm.afm文件(字体度量文件)嵌入(因为 PDF 查看器有这些内部知识)。没有这些,字体文件很难以一种视觉上令人满意的方式使用。

使用 fontforge

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

  1. 使用打开文件时使用的 “开放字体”对话框。
  2. 然后在对话框的过滤器部分选择 PDF 摘录
  3. 选择要提取字体的 PDF 文件。
  4. 将打开一个 “选一种字体”对话框——在这里选择要打开的字体。

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


使用 mupdf

下一个, MuPDF 。这个应用程序附带了一个名为 pdfextract的实用程序(在 Windows 上: pdfextract.exe) ,它可以从 PDF 中提取字体和图像。(如果你不知道 MuPDF,它仍然是相对未知和新的: “ MuPDF 是一个免费的轻量级 PDF 浏览器和便携式 C 编写的工具包”,由 Artifex 软件开发人员编写,同一家公司给了我们 Ghostscript。)
(更新版本的 MuPDF 已经将以前的 「 pdf 摘录」功能移动到命令 “ mutool 萃取物”

注意: 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 等。如果图像的 PDF 对象编号为412,则图像名称将类似于 Img-0412. png。如果字体的 PDF 对象编号为966,则字体名称将类似于 FGETYK + L inLibertineI-0966. ttf

CFF (紧凑型字体格式)文件是一种可识别的格式,可以通过各种转换器转换为其他格式,以便在不同的操作系统上使用。

再次强调: 注意这些字体文件中的大多数可能只有 子集字符,并且可能不代表完整的字体。

更新: (2013年7月)最近版本的 mupdf已经看到了它们的二进制文件的内部重组和重命名,不只是一次,而是好几次。主要的实用程序曾经是一个类似于“瑞士刀”的二进制文件,称为 mubusy(名字的灵感来自 busybox?)最近更名为 mutool。它们支持子命令 infocleanextractpostershow。不幸的是,这些工具的官方文档还没有更新。如果您在 Mac 上使用“ MacPorts”: 那么为了避免与使用相同名称的其他实用程序的名称冲突,该实用程序被重命名,您可能需要使用 mupdfextract

要获得与之前的工具 pdfextract相同的(大致) mutool结果,只需运行 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)

然后,< strong > Ghostscript 还可以直接从 PDF 中提取字体。但是,它需要一个名为 强 > extractFonts.ps的特殊实用程序的帮助,该程序是用 PostScript 语言编写的,可以从 原始码储存库获得。

现在使用它,您需要同时运行这个文件 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 的 < strong > pdf-parser.py : 这个可能不太容易使用,因为你需要一些关于内部 PDF 结构的诀窍。pdf-parser.py是一个 Python 脚本,它也可以做很多其他的事情。它还可以从对象中解压缩和提取任意流,因此也可以提取嵌入式字体文件。

但你得知道要找什么。让我们看一个例子。我有一个名为 Big.pdf的文件。作为第一步,我使用 -s参数在 PDF 中搜索任何出现的关键字 字体文件(pdf-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
>>

它告诉我 PDF 中有两个 FontFile2实例,分别在 PDF 对象编号15和编号16中。对象15保存字体 /ArialMT/FontFile2,对象16保存字体 /Arial-BoldMT/FontFile2

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

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’包含字体程序的流,其格式由流字典中的子类型条目指定’相关(因此是 1C 型CIDFontType0C亚型)

要特别查看 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 进行编码(= = “压缩”) ,需要在标准 /ASCIIHexDecode过滤器的帮助下进行解码(= = “解压缩”或“过滤”)。

要从对象转储任何流,可以使用 -d dumpname参数调用 pdf-parser.py:

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

我们提取的数据转储将在名为 转储数据的文件中。让我们看看它有多大:

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

太好了!,我们有一个赢家: pdf-parser.py的确提取了一个有效的字体文件给我们。考虑到这个文件的大小(778.552字节) ,看起来这种字体已经嵌入甚至 彻底的在 PDF..。

我们可以将它重命名为 常规的,并按照这样的方式安装它,然后愉快地使用它。


警告:

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

  • 大多数 PDF 文件都是在野外那里不嵌入完整的字体无论如何,但只有子集。提取字体的子集只有在非常有限的范围内才有用,如果有的话。

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

最终找到了 FontForge Windows Installer 软件包,并通过安装的程序打开了 PDF。

PDFTron的 PDF2SVG 版本6.0做得相当不错。默认情况下,它生成 OpenType (.otf)字体。使用 --preserve_fontnames保留“从源文件获得的 font/font-family 命名方案”

PDF2SVG 是一个商业产品,但是您可以下载一个免费的演示可执行文件(其中包括 SVG 输出上的水印,但是不限制使用)。可能还有其他 PDFTron 产品也提取字体,但是我自己最近才发现 PDF2SVG。

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

目前提取 pdf 字体最好的在线工具之一是 http://www.pdfconvertonline.com/extract-pdf-fonts-online.html

这是 @ Kurt Pfeifle 的回答font-forge部分的后续内容,特定于 Red Hat (可能还有其他 Linux 发行版)。

  1. 打开 PDF 并选择所需的字体后,您需要选择“ File-> Generate Fonts...”选项。
  2. 如果文件中有错误,您可以选择忽略它们或保存文件并编辑它们。如果你点击“修复”足够多次,大多数错误都可以自动修复。
  3. 单击“ Element-> Font Info...”,“ Fontname”、“ Family Name”和“ Name for Human”都设置为您喜欢的值。如果没有,修改它们并将文件保存到某个地方。这些名称将决定您的字体在系统上的显示方式。
  4. 选择您的文件名,然后单击“保存...”

获得 TTF 文件后,可以通过以下方法将其安装到系统上

  1. 将其复制到文件夹 /usr/share/fonts(作为根用户)
  2. 运行 fc-cache -f /usr/share/fonts/(作为 root 用户)

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

在搜索当前的答案时,没有人注意到 WOFF (Web Open Font Format)(W3C)(维基百科) ,它可以用来重新创建单个字符(字形) ,并在网页上准确地显示它们。

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

WOFF 文件可以在 WOFFER-WOFF 字体转换器上从 OTF 或 TTF 转换为/

此外,从 PDF 到 HTML5的压缩文件将包含一个 HTML 文件的 PDF 的每一页,可以在互联网浏览器中打开,是最好的和最准确的 PDF 翻译之一,我已经找到或看到。

虽然我正在学习如何使用 WOFF 文件,但是这是值得传授的。

另外,随着我对 woff 文件类型的了解越来越多,我可能会更新更多的信息,但是由于这是知识共享,如果你有什么有价值的东西要传递,请随意编辑这个答案。