首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何确定线性化PDF文件中第1页的范围(以字节为单位)?

如何确定线性化PDF文件中第1页的范围(以字节为单位)?
EN

Stack Overflow用户
提问于 2012-04-10 22:32:36
回答 1查看 2K关注 0票数 8

我知道我可以“线性化”一个PDF文件,例如使用Acrobat或使用商业工具。这也被称为“为web优化”,它重新排列PDF,以便页面1可以尽快加载。以这种方式服务的PDF会更快地显示,因为PDF查看器不需要等待整个PDF被下载。

更新:基于下面答案的,我现在意识到线性化的PDF不仅被重新排列,而且还包含关于其自身结构的元数据,其形式是“线性化字典”。

我有一个应用程序,在该应用程序中,我希望预取几个PDF(查询的结果),希望用户能够看到其中的一个。如果我的客户能够为每个搜索结果下载第1页,而只下载第1页,那就太棒了。当用户选择其中之一时,页面1可以立即显示,其余部分可以在后台下载。

我正在寻找一个通用的解决方案,可以使用服务器端(Windows或Linux)对我的PDF进行预处理,这样我就可以分别存储和服务页面1和其余部分。实际上,我需要知道的是PDF中的最后一个字节是正确显示第1页所需的。

我已经浏览了PDF的ISO规范,但是文件格式似乎太复杂了,我无法简单地解析出第1页结束的位置。另一方面,线性化PDF的工具几乎肯定知道第1页的结尾位置。

我对向客户端提供分段PDF的复杂情况并不感兴趣;这部分已经解决了,因为客户端是一个应用程序,而不是浏览器,而且我可以完全控制。

我也不认为它会帮助我使用像AP分裂这样的工具将PDF分割成一个“第1页”的PDF和一个完整的PDF。如果我这样做了,那么我将无法欺骗客户端查看器认为它是一个单一的PDF文件,当我用完整的PDF替换“第1页”PDF时,会出现明显的闪烁。

任何帮助或指示都很感激。

解决方案(基于Bobrovsky以下的回答):

正确线性化的PDF以标题行(在PDF规范第7.5.2节中定义)开始,如"%PDF-1.7“,后面是至少四个二进制字符的注释行(定义为128个或更高的字节值)。例如:

代码语言:javascript
复制
    %PDF-1.7
    %¤¤¤¤

这个标题紧接着是线性化字典(在PDF规范的附录F中定义)。举个例子:

代码语言:javascript
复制
    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。这个数据结构非常简单,几乎可以使用任何语言进行解析。“430obj”给出了这个字典的ID (43)和一个生成号(线性化文件总是为零)。字典本身被<<和>>包围,其中包括键值对(键有类似于“/E”的斜杠)。

下面是一个使用regex查找相关数字的C#方法:

代码语言:javascript
复制
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本身。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-04-11 08:15:12

线性化字典应该能帮助你做到这一点。

包含E参数所需的字典,即

第一页末尾的偏移量(例如F.1中第6部分的结尾),相对于文件的开头。

请注意,并非每一个具有线性化字典的文件实际上都是线性化的(损坏的生成器、线性化后的更改等)。因此,如果您的文件未被验证为正确地线性化,您可能无法使用描述的方法。

有关线性化字典的更多信息,请参阅PDF参考中的F.2.2线性化参数字典(第2部分)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10097407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档