更改完成的 PDF 文件中的颜色

更改完成的 PDF 文件中的颜色

假设我有一个完成的 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生成TeXLive2018PDF文件没有硬存储的黑色,但事实证明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、和来代替。RGkK

上面的编辑命令可能不够具体。在我看到的文件中,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。)Gperl"'

警告:生成的 PDF 文件仍未压缩。如果不压缩,则将其包含在其他文件中会增加其大小(不必要)。(pdftk在 Heiko 的答案中使用compress而不是 的命令uncompress。)

相关内容