PDF 格式¶
建议查阅 PDF 规范 来获取详细信息和进一步澄清。
ISO 32000-2:2020 (PDF 2.0)
以下内容仅为该格式的大致概述。
整体结构¶
一个 PDF 文件包括:
头部 (Header):包含 PDF 的版本,例如
%PDF-1.7
主体 (Body):包含一系列间接对象 (indirect objects)
交叉引用表 (xref):包含主体中间接对象的列表
尾部 (Trailer)
交叉引用表 (xref)¶
交叉引用表是主体中间接对象的一个索引表,它通过指向文件中的具体位置,实现对对象的快速访问。
其结构如下:
xref 42 5
0000001000 65535 f
0000001234 00000 n
0000001987 00000 n
0000011987 00000 n
0000031987 00000 n
逐行解析:
xref
:标识交叉引用表的开始。42
:当前 xref 部分中第一个对象的编号;5
表示 xref 表中条目的总数。每个对象条目格式为
nnnnnnnnnn ggggg n
:nnnnnnnnnn
:对象的字节偏移量,指出对象在文件中的位置。ggggg
:对象的生成号,表示对象的版本历史。n
表示该对象为正常使用对象,f
表示该对象为空闲对象。第一个空闲对象的生成号始终为
65535
,它是所有空闲对象链表的头部。正常对象的生成号始终为
0
。生成号允许 PDF 文件包含同一对象的多个版本,用于版本控制机制。
主体 (Body)¶
主体由一系列间接对象组成,格式如下:
counter generation_number << the_object >> endobj
counter
(整数):对象的唯一标识符。generation_number
(整数):对象的生成号。the_object
:对象本身,可以为空。以/Keyword
开头,指定对象类型。endobj
:标识对象的结束。
示例(摘自 test_reader.py::test_get_images_raw
):
1 0 obj << /Count 1 /Kids [4 0 R] /Type /Pages >> endobj
2 0 obj << >> endobj
3 0 obj << >> endobj
4 0 obj << /Contents 3 0 R /CropBox [0.0 0.0 2550.0 3508.0]
/MediaBox [0.0 0.0 2550.0 3508.0] /Parent 1 0 R
/Resources << /Font << >> >>
/Rotate 0 /Type /Page >> endobj
5 0 obj << /Pages 1 0 R /Type /Catalog >> endobj
尾部 (Trailer)¶
尾部的格式如下:
trailer << /Root 5 0 R
/Size 6
>>
startxref 1234
%%EOF
逐行解析:
trailer <<
:标识尾部字典的开始,以>>
结束。startxref
:一个关键字,后面跟随xref
关键字的字节位置。由于尾部始终位于文件末尾,这使得读取器可以快速定位到 xref 表。%%EOF
:文件结束标识。
尾部字典是一个键值对列表。键的定义见 PDF 参考规范 1.7 的表 15,例如 /Root
和 /Size
(这两个键是必须的):
/Root
(字典):包含文档目录。5
:目录字典的对象编号。0
:目录字典的生成号。R
:表示该对象是对目录字典的引用。
/Size
(整数):表示 xref 表中的条目总数。
读取 PDF 文件¶
大多数 PDF 文件是经过压缩的。如果要读取它们,首先需要解压:
pdftk crazyones.pdf output crazyones-uncomp.pdf uncompress
然后将 crazyones-uncomp.pdf
重命名为 crazyones-uncomp.txt
,并在你喜欢的 IDE 或文本编辑器中打开它。