多个 PDF 中包含页面组,但页面组包含在单个页面中,警告

多个 PDF 中包含页面组,但页面组包含在单个页面中,警告

我将 TeX Live 更新到 Ubuntu Quantal 版本(2012.20120611-4)后突然收到此警告:

PDF 包含:将多个带有页面组的 PDF 包含在一个页面中

这是我收到警告的一个小例子:

\documentclass{book}
\usepackage{graphicx}
\begin{document}
  \includegraphics{image1}

  \includegraphics{image2}
\end{document}

这两幅图像都是通过 Inkscape 的导出 PDF 功能生成的,包含简单的线条图(没有花哨的东西)。

我一直在互联网上寻找,但只发现其他人有这个问题,并没有找到任何解决方案:

  • 在里面Latex 用户组他们似乎不理解/不承认这个问题。并告诉原帖者去 MikTeX 小组,但这不是 MiKTeX 特有的问题,因为 TeX Live 和其他发行版也存在这个问题。

  • gmane.comp.tex.pdftex他们正在调查 MS Office 产品的使用情况(和版本)。这也不是原因,因为我没有使用 MS Office 来制作 PDF。

在我搜索的过程中,如果发现 PDFTeX 代码(pdftoepdf.cc) 会产生这个警告,也许它有助于理解正在发生的事情?

if (pdfpagegroupval == 0) { 
    // another pdf with page group was included earlier on the same page;
    // copy the Group entry as is
    pdftex_warn("PDF inclusion: multiple pdfs with page group included in a single page");
    pdf_newline();
    pdf_puts("/Group ");
    copyObject(&dictObj);
} else {
    // write Group dict as a separate object, since the Page dict also refers to it
    pageDict->lookup((char *) "Group", &dictObj);
    if (!dictObj->isDict())
        pdftex_fail("PDF inclusion: /Group dict missing");
    writeSepGroup = true;
    initDictFromDict(groupDict, page->getGroup());
    pdf_printf("/Group %d 0 R\n", pdfpagegroupval);
}

有人知道发生了什么事、是否严重以及如何摆脱这些警告?

答案1

该问题还报告在德国论坛 mrunix.de。这可能是 tex 发行版 (pdftex) 中的一个错误。仅当您在单个页面中包含以特定方式(例如,通过 MS Office 产品)创建的多个 pdf 页面时,才会发生此问题。

解决方案: 使用 Ghostscript 将 pdf 文件转换为 ps,然后再转换为 pdf,警告就会消失(pdf2ps -> ps2pdf)。此转换可能会从 pdf 文件中删除“页面组”信息。(警告:这会使您的 pdf 和某些文本不再可选或可搜索。)

使用 ghostscript 编辑 pdf 文件的色彩空间也可以解决问题(如果 pdf 文件中没有多页):

gs -o fixed-image.pdf -sDEVICE=pdfwrite -dColorConversionStrategy=/sRGB 
   -dProcessColorModel=/DeviceRGB original-image.pdf

如果 RGB 不适合您,请进行 CMYK 转换:

gs -o fixed-image.pdf -sDEVICE=pdfwrite -dColorConversionStrategy=/CMYK 
   -dProcessColorModel=/DeviceCMYK original-image.pdf

附言一些程序会在 pdf 文件中生成“页面组”;例如,当您在 illustrator 或 inkscape 中拼贴不同的图像/对象时。pdftex 似乎无法在单个输出页面中处理多个页面组。原因可能是每个页面组指定了不同的颜色空间或透明度空间。

答案2

PDF 有一个称为“页面组”的功能(PDF 参考,第 11.4.7 节)。这些描述了同一页面上的顶层对象之间的透明效果。当 pdfTeX(或 LuaTeX 或 XeTeX)包含 PDF 中的页面时,它会将所有页面转换为“Form XObjects”(第 8.10.1 节)。pdfTeX 还将页面组转换为/GroupXObjects 的条目。

现在的问题是,Adobe 产品还需要包含这些 XObjects/Group的对象中的一个条目(其内容无关紧要)/Page才能正确呈现透明度(这只是为了选择正确的渲染引擎;包含页面的透明度信息应该从这些包含的页面中获取)。

pdfTeX 将在包含 PDF 时使用遇到的第一个文件/Group,或者在包含具有透明度的 PNG 时合成一个。警告当一个页面上遇到多个页面组时触发(因为引擎将使用遇到的第一个页面组,而这可能不是“正确的”页面组),并且或许可以忽略。当然这应该在 pdfTeX 文档的某个地方描述......


更新 2016-03-30

从版本 1.40.15 (TeXlive 2014) 开始,pdfTeX 有一个参数\pdfsuppresswarningpagegroup

通常,当包含的多个 pdf 文件具有所谓的“页面组对象”(/Group)时,pdfTeX 会发出警告,因为只有一个可以“获胜”——即传播到页面级别。通常页面组是相同的,但如果不相同,结果将无法预测。如果 pdfTeX 实际上可以检测页面组是否相同并且只在有问题的情况下发出警告,那将是理想的;不幸的是,这并不容易(欢迎修补)。尽管如此,人们经常会发现实际上没有问题。那么每次运行时看到的警告只是噪音,可以通过将此参数设置为正数来抑制。

因此,通过添加到\pdfsuppresswarningpagegroup=1文件顶部,您可以抑制此警告。

答案3

马丁·施罗德已经很好地解释了根本原因,所以我就不重复了。除了告诉 pdfLaTeX 闭嘴,解决办法是从 PDF 输入中删除/剥离页面组然而,所有提出的解决方案似乎都存在以下问题之一:

  • 有损:Ghostscript 相关解决方案显然会将 PDF 文件栅格化,这完全违背了使用 PDF 图形的意义!我对图像质量非常挑剔,所以这个方向行不通。
  • 脆弱的:单纯地使用查找和替换(即sed)来修复 PDF 文件可能不是一个好主意。这可能会损坏 PDF 文件。

原来有一款很棒的开源工具,叫做定量PDF,它可以将 PDF 文件“解压”为常规的准文本格式,昵称“QDF”。运行此工具后,使用纯文本编辑器很容易识别 QDF 文件中的页面组。下面显示了一个片段:

%% Page 1
%% Original object ID: 5 0
4 0 obj
<<
  /Contents 5 0 R
  /Group <<
    /CS /DeviceRGB
    /I true
    /S /Transparency
    /Type /Group
  >>
  /MediaBox [
    0
    0
    460.799988
    345.600006
  ]
  /Parent 3 0 R
  /Resources 7 0 R
  /Type /Page
>>

我是在 Inkscape 中创建的。你的可能有点不同。注意字典/Group << … >>。这是需要删除的。可以使用 Python 脚本自动完成此操作:

import re, sys

stdin = getattr(sys.stdin, "buffer", sys.stdin)
stdout = getattr(sys.stdout, "buffer", sys.stdout)
stderr = getattr(sys.stderr, "buffer", sys.stderr)

page_group = None
for line in stdin:
    if page_group is None:
        if line.rstrip() == b"  /Group <<":
            page_group = [line]
        else:
            stdout.write(line)
    else:
        page_group.append(line)
        if line.rstrip() == b"  >>":
            break
else:
    if page_group:
        stdout.write(b"".join(page_group))
        page_group = None
for line in stdin:
    stdout.write(line)
stdout.flush()

if page_group:
    stderr.write(b"".join(page_group))
else:
    stderr.write(b"note: did not find page group\n")

保存该脚本,然后strip_page_group.py将所有命令链接在一起:

qpdf --qdf input.pdf - | python strip_page_group.py | fix-qdf >output.pdf

注意 1:确保输出文件名 ( output.pdf) 与输入文件名 () 不同input.pdf,否则您将完全丢失 PDF 文件!

注 2:如果需要确定性输出,请提供qpdf--deterministic-id选项。

答案4

针对 MS Office 用户的附加信息/解决方法:多年来,我一直在使用 pdfLaTeX 和 Visio 生成的 PDF。我刚刚重新安装了 PC,然后收到了警告 - 但只针对新保存的 PDF,而不是旧 PDF。因此,我在 Visio 中寻找 PDF 选项:如果您告诉 Visio 生成兼容 PDF/A 的 PDF,警告就会消失。

相关内容