假设我有一个完成的 PDF 文件,比如某个软件生成的一个图形,其中的墨水是黑色的。我会将它包含在文档中。假设我想将它包含在beamer
具有黑色背景的演示文稿中。
有没有办法配置包含内容,以便我可以指定黑色的内容应显示为白色?如果没有,我可以使用哪些命令行工具来处理 PDF 文件?
答案1
使用无色 PDF 和 pdfTeX 的简单情况(不幸的是很少见):
PDF 文件包含一些没有明确颜色设置的图纸,图像将由图形包的 pdftex 驱动程序包含。
下面的文件会生成这样的图像:
\documentclass{article}
\usepackage[active,tightpage,floats]{preview}
\begin{document}
\begin{figure}
\Huge\bfseries\sffamily
\setlength{\fboxrule}{2pt}
\fbox{Hello World}
\end{figure}
\end{document}
以下文件包含图像(t.pdf)并改变其颜色。
\documentclass{article}
\usepackage{color}
\usepackage{graphicx}
\pagecolor{black}
\color{white}
\begin{document}
\Huge\bfseries
\noindent
Some text.\\
\includegraphics{t.pdf}\\
Some text.\\
\textcolor{yellow}{\includegraphics{t.pdf}}\\
Some text.
\end{document}
此技巧不适用于其他驱动程序,因为其他驱动程序在包含图像之前会将颜色标准化。如果为 pdftex.def 提供了选项,则颜色将在包含图像期间resetcolor
设置为。\normalcolor
手动颜色修复
了解一些内部结构后,可以手动修复 PDF 文件。首先需要解压缩压缩的页面内容,例如:
pdftk test.pdf cat output test-uncompress.pdf uncompress
然后需要识别页面内容流,并且可以更改或删除颜色操作(通过用空格覆盖)。最好不要更改对象的大小,否则需要更新外部引用表中对象的文件偏移量。顺便说一句,PDF(或 PS)也使用%
注释字符。然后可以重新压缩文件。
或者将 PDF 文件转换为 PostScript(例如,使用 xpdf 中的 pstopdf)。如果更改文件大小无关紧要,则编辑会更容易。PostScript 没有外部引用表。但是,检测颜色操作符可能更困难,因为它们通常在程序中被重命名或隐藏。与 PDF 不同,PostScript 是一种编程语言。
处理矢量图像的程序,例如 Inkscape
如果 PDF 文件可以成功导入 Inkscape 或类似程序,则可以在那里更改颜色。
位图转换
作为最后的手段,可以将图像转换为位图图像(ghostscript 和其他转换器)。这意味着由于像素数据而导致质量损失。但许多图像处理程序应该能够改变颜色。
甚至可以通过 pdftex.def 支持的 PDF 格式功能生成反转颜色。可以通过数组反转颜色/Decode
(带有索引颜色空间的图像除外)。每个颜色成分都有两个介于 0 和 1 之间的浮点值。因此必须知道颜色成分的数量(Mono:1、RGB:3、CMYK:4)
\includegraphics[decodearray=1 0 1 0 1 0]{rgbimage.png}
例如,ghostscript 设备png16m
可用于生成用于此用途的 PNG。PDF 参考中解释了更多详细信息。pdftex.def 的选项在文件本身中进行了简要说明。
答案2
昨天,我一直在努力解决类似的问题:虽然xelatex
生成TeXLive2018
的PDF
文件没有硬存储的黑色,但事实证明TeXLive2021
生成的文件具有不可变的黑色。(这可能是由于xdvipdfmx
的版本更改20180217 → 20210318
。这破坏了我的使用场景 我的“表情符号包含者”。
差异是由于生成的PDF
文件中的以下变化(添加了空格):
- q 1 0 0 1 72 -62.967 cm 0 G 0 g 0 g 0 G BT /F1 9.9626 Tf -72 64.65 Td[<1841>]TJ ET Q
+ q 1 0 0 1 72 -62.967 cm BT /F1 9.9626 Tf -72 64.65 Td[<1841>]TJ ET Q
PDF 对象内部stream
是每个 PDF 对象的内容/Type /Page
(上面的页面仅包含由 [<1841>] 索引的字形)。
我的解决方法
解压后,运行
perl -wpe "BEGIN{binmode STDIN; binmode STDOUT} s/(?<!\S)(0\s+[gG])(?!\S)/q( ) x length $1/ge" emoji-from-list-uncompress.pdf >emoji-from-list-nocolor.pdf
总体而言,这与 Heiko 在本页的回答和 sebschub 在本回答的评论一致。不过,我们在本评论中删去了g
和命令,G
而用rg
、和来代替。RG
k
K
上面的编辑命令可能不够具体。在我看到的文件中,g
/ G
⸣ 成组出现。因此命令
perl -wpe "BEGIN{binmode STDIN; binmode STDOUT} s/(?<!\S)((0\s+[gG]\s*?){2,})(?!\S)/q( ) x length $1/ge" emoji-from-list-uncompress.pdf >emoji-from-list-nocolor.pdf
可能更加健壮。它会连续查找至少 2 个 black- g
-or-命令。(这些命令采用 Windows 的 shell 语法。在 Unixy 系统上将⸣s 更改为⸣s。)G
perl
"
'
警告:生成的 PDF 文件仍未压缩。如果不压缩,则将其包含在其他文件中会增加其大小(不必要)。(pdftk
在 Heiko 的答案中使用compress
而不是 的命令uncompress
。)