将PDF中的所有字形替换为轮廓形状,通过将它们转换为轮廓形状来实现

23
我正在寻找一种方法来将 PDF 文件中的所有文本/字体轮廓化,即将它们转换为曲线。 我希望能够在不必将 PDF 转换为 PostScript 并再次转换回 PDF 的情况下实现。此外,我想使用免费轻量级跨平台工具,例如 Ghostscript 或 MuPDF,并且可以通过命令行自动化。

LaTeXiT可以实现这一点,我相信它使用GhostScript(但不确定)。我试图查看源代码并找出它是如何实现的,但未能成功。 - Szabolcs
Ghostscript现在可以做到这一点,但以前并不容易做到(您必须通过PostScript)。我已经将信息添加为下面的答案。 - KenS
使用广告拦截器的 PDF-TEXT-To-Outlines 在处理一次性隐私不敏感文档方面表现良好。 - tejasvi88
@tejasvi88 然而,它不是一个可以轻松自动化的命令行工具,这正是我所寻找的。 - Szabolcs
3个回答

44

是的,您可以使用Ghostscript来实现您想要的功能。

I. 对于Ghostscript版本9.14及以下

您需要经过2个步骤:

  1. 将PDF转换为PostScript文件,但使用一个相对不太知名的参数的副作用:-dNOCACHE。这将把所有已使用的字体转换为轮廓形状:

    gs -o somepdf.ps -dNOCACHE -sDEVICE=pswrite somepdf.pdf
    
  2. 将PS文件转换回PDF文件(如果需要,可以再次删除中间的PS文件):

  3. gs -o somepdf-with-outlines.pdf -sDEVICE=pdfwrite somepdf.ps
    
    rm somepdf.ps
    

这种方法不够可靠,因为Ghostscript开发人员已经表示-dNOCACHE可能在未来的版本中不存在。

注意: 生成的PDF文件很可能比原始文件大。此外,如果没有额外的命令行参数,原始PDF中的所有图像也很可能根据Ghostscript内置默认值进行处理,这可能会导致不良影响。增加更多的命令行参数以进行其他处理可以避免这些副作用。


二、Ghostscript 版本 9.15 或更新版本

Ghostscript 9.15 版本(于2014年9月发布)支持一个新的命令行参数:

 -dNoOutputFonts

这将导致输出设备pdfwriteps2writeeps2write将字形“压扁”成“基本”的标记操作(而不是将字体写入输出)。

这意味着:可以避免预9.15 GS版本中描述的两个步骤。只需一个命令即可实现所需的结果:

 gs -o file-with-outlines.pdf -dNoOutputFonts -sDEVICE=pdfwrite file.pdf

注:与第一部分已经注意到的相同,如果您的PDF包含图像,则上面的简单命令行可能会引入不必要的副作用。为了避免这些问题,您需要添加更具体的参数。


嗨 Kurt,我已经创建了一个包含图像、标题和表情符号的相册 PDF,并且需要打印该 PDF。将任何相册 PDF 转换为“打印就绪”PDF 格式的理想方法是什么?在 ghostscript 中有哪些选项可供使用?你能指导我或指向一些资源吗?非常感谢您的帮助。实际上,我尝试通过您在此答案中提到的命令来概述我的 photobook pdf 中的字体...它运行良好。但由于此 PDF 包含图像、表情符号、文本...我不确定是否是确切的命令?还是我需要在更长时间内使用一些额外的选项...? - Kaviraj Kanagaraj
@Kurt,回答的很好,你真的应该添加一个链接到你的另一个答案,关于如何保持光栅图像分辨率:https://superuser.com/a/373740/207447 - Libin Wen
-dNoOutputFonts 添加一个相关文档参考。但请注意,由Ghostscript创建的新输出PDF文件默认设置下不一定更加“智能”(从臃肿的输入PDF获得更小、更优化的文件)。另请参见 如何使用ghostscript删除PDF中的重复对象? - samm

11

这个提交记录为Ghostscript的pdfwrite和ps2write设备添加了一个新的开关-dNoOutputFonts,它将生成一个PDF文件(或后缀为选定设备的PostScript文件),其中所有字形都是矢量图形,而不是文本。

您至少需要Ghostscript 9.15版本才能使用此功能。请注意,PDF文件几乎肯定会更大,复制/粘贴/搜索将(显然)无法使用。


是的,我测试了一下,发现导致文件变大的原因不仅仅是将字体转换为轮廓形状/向量/曲线。例如,我有一个PDF文件,其中嵌入了一个水印图像,并在每个页面上引用/间接使用。经过ghostscript处理后,我发现输出的PDF文件在每个页面上都包含重复的图像,使用了itext-rups-7.1.11.jar页面: ... 第3页 124 0 R => 图像流 第4页 171 0 R => 图像流 ... XRef: ... 124 => 图像流 171 => 图像流 ... - samm
上面的评论似乎与原问题或答案无关。如果您有问题,请samm提出一个新问题。对于其他读者,Ghostscript的pdfwrite设备(默认情况下)将哈希所有图像,并仅在它们相同的情况下使用一个。当然,samm没有提供输入文件、命令行、输出文件甚至是Ghostscript的哪个OS或版本的信息,这使得调查或评论变得不可能。 - KenS
好的,似乎与将文本转换为未嵌入字体的曲线没有什么关系。我只是想添加一条关于输出PDF文件较大的大小的注释,如果有人担心大小的话。我在Windows 10上使用gs v9.52通过 gs -o book.vectored.pdf -dNoOutputFonts -sDEVICE=pdfwrite book.optimized.pdf,生成了300多页的PDF。我对book.vectored.pdf使用了与book.optimized.pdf相同的优化算法,可以将其大小减小10 MB。 - samm

0

III. Ghostscript版本9.54.0(Windows 10)

我找到了一种方法,可以将所有字体完美地保留为向量,而且没有任何视觉错误,只需两个打印步骤,在正确安装和配置Ghostscript之后。

(注意!您必须将Ghostscript bin-/和lib文件夹添加到Windows PATH中,才能让Ghostscript执行任何操作) 此处有说明

  1. 使用Acrobat Reader和Microsoft PS Class Driver将包含矢量字体或其他矢量元素的PDF文件打印到YourFile.prn文件中。(安装此驱动程序--控制面板-设备-打印机和扫描仪-添加打印机或扫描仪--让Windows先查找一段时间连接的打印机,当它停止时选择一个选项--我想要的打印机未列出-添加本地打印机或网络打印机,手动设置-下一步-使用现有端口:>文件:(打印到文件)-下一步-Microsoft:Microsoft PS Class Driver-下一步)

  2. 打开命令提示符,导航到YourFile.prn文件所在的文件夹,并键入:"C:\Program Files\gs\gs9.54.0\bin\gswin64c.exe" -dNOPAUSE -dNOCACHE -dBATCH -sDEVICE=eps2write -sOutputFile=YourFile.eps YourFile.prn

如果您经常需要执行此操作,还可以创建包含以下内容的prn2eps.bat文件:

"C:\Program Files\gs\gs9.54.0\bin\gswin64c.exe" -dNOPAUSE -dNOCACHE -dBATCH -sDEVICE=eps2write -sOutputFile=%1.eps %1.prn

要使用那个批处理文件,你只需要输入:prn2eps YourFile(注意!你必须将批处理文件和Yourfile.prn放在同一个目录下)

由于某种原因,在Windows 10中,最新的Ghostscript ps2epsi函数无法正常工作,并且Adobe制作的PDF文件在我将它们导入非Adobe设计软件作为PDF文件时,某些字体字符存在一些小但一致的错误。多年来,我发现EPS文件格式是保留矢量图形从一个软件到另一个软件最可靠的格式之一。许多时候,仅使用另一个打印机驱动程序再次将PDF打印为PDF可能足够,或者使用Ghostscript进行单个文件格式更改,但并非总是如此。


1
“II”解决方案在Ghostscript 9.54中仍然像以前一样有效(我经常使用它)。其他答案并不依赖于GSView。我不确定你的答案试图解决什么问题。 - Szabolcs
我确实尝试了那个解决方案,但由于某些原因,一些特定的字体仍然存在一些错误(一些变形的字符,就像缺少一些顶点或控制向量),只有在使用Windows 10自带驱动程序打印第一个PS,然后将其转换为EPS时才能修复。我已经使用Ghostscript数十年来修复矢量文件转换中的所有奇怪视觉错误,这是一个很棒的工具!Gsview使它变得非常容易使用,因为它有一个图形界面,但现在不再可用。 - Supernuija
1
如果您在答案中解释您的解决方案要解决的问题,那对读者会很有帮助。 - Szabolcs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接