我知道我可以“线性化”PDF 文件,例如使用 Acrobat SDK 或使用商业工具。这也称为“针对 Web 优化”,它重新排列 PDF 以便可以尽快加载第 1 页。以这种方式提供的 PDF 显示得更快,因为 PDF 查看器不必等待整个 PDF 被下载。
更新:根据下面的答案,我现在意识到线性化 PDF 不仅重新排列,而且还包含有关其自身结构的元数据,以“线性化字典”的形式。
我有一个应用程序,我想预取几个 PDF(查询的结果),以期用户希望看到其中一个。如果我的客户可以为每个搜索结果下载第 1 页,并且只下载第 1 页,那就太棒了。当用户选择其中之一时,可以立即显示第 1 页,其余的可以在后台下载。
我正在寻找一种可用于服务器端(Windows 或 Linux)来预处理我的 PDF 的通用解决方案,以便我可以分别存储和提供第 1 页和其余部分。真的,我只需要知道 PDF 中正确显示第 1 页所需的最后一个字节的位置。如果我能得到这个数字,那么其他所有内容都将随之而来。
我浏览了PDF 的 ISO 规范,但文件格式似乎太复杂,无法简单地解析出第 1 页的结束位置。另一方面,线性化 PDF 的工具必须几乎肯定知道第 1 页的结束位置。
我对将 PDF 分段提供给客户的复杂性不感兴趣;这部分已经解决,因为客户端是一个应用程序,而不是浏览器,我可以完全控制。
我也不认为它会帮助我使用AP Split之类的工具将 PDF 拆分为“第 1 页”PDF 和完整的 PDF。如果我这样做了,那么我将无法欺骗客户查看者认为它是单个 PDF 文件,并且当我将“第 1 页”PDF 替换为完整 PDF 时会出现明显的闪烁。
任何帮助或指针表示赞赏。
解决方案(基于以下 Bobrovsky 的回答):
正确线性化的 PDF 以标题行(在 PDF 规范的第 7.5.2 节中定义)开始,例如“%PDF-1.7”,后跟至少四个二进制字符的注释行(定义为 128 或更高的字节值) . 例如:
%PDF-1.7
%¤¤¤¤
此标头后紧跟线性化字典(在 PDF 规范的附录 F 中定义)。一个例子:
43 0 obj
<< /Linearized 1.0 % Version
/L 54567 % File length
/H [475 598] % Primary hint stream offset and length (part 5)
/O 45 % Object number of first page’s page object (part 6)
/E 5437 % Offset of end of first page
/N 11 % Number of pages in document
/T 52786 % Offset of first entry in main cross-reference table (part 11)
>>
endobj
在这个例子中,第一页的结尾在字节偏移 5437 处。这个数据结构非常简单,可以使用几乎任何语言进行解析。“43 0 obj”这个东西给出了这个字典的一个 ID (43) 和一个代号(对于线性化文件总是零)。字典本身被 << 和 >> 包围,它们之间是键值对(键有像“/E”这样的斜线)。
这是一个使用正则表达式查找相关数字的 C# 方法:
public int GetPageOneLength(byte[] data)
{
// According to ISO PDF spec: "The linearization parameter dictionary shall be entirely contained within the first 1024 bytes of the PDF file" (p. 679)
string preamble = new string(ASCIIEncoding.ASCII.GetChars(data, 0, 1024)); // Note that the binary section on line 2 of the header will be entirely converted to question martks ('?')
var match = Regex.Match(preamble, @"<<\w*/Linearized.+/E\s+(?<offset>\d+).+>>");
if (!match.Success) throw new InvalidDataException("PDF does not have a proper linearization dictionary");
return int.Parse(match.Groups["offset"].Value);
}
请注意 Bobrovsky 的警告,即文件可能包含线性化字典,但可能未正确线性化(可能是因为增量编辑?)。就我而言,这不是问题,因为我将自己线性化所有 PDF。