PDF 基础数据

471 阅读5分钟

PDF(Portable Document Format)是一种广泛使用的文档格式,由 Adobe 公司开发。了解 PDF 的基础数据结构对于深入理解 PDF 文件格式和进行 PDF 处理非常重要。本文将详细介绍 PDF 文件中的基本数据结构。

目录

1. PDF 文件的基本结构

PDF 文件由以下几个主要部分组成,每个部分都有其特定的功能和格式。

1.1 文件头(Header)

文件头是 PDF 文件的开始部分,包含版本信息和标识符。

%PDF-1.7
%¥±ë

💡 说明

  • 第一行 %PDF-1.7 指定 PDF 版本为 1.7
  • 第二行 %¥±ë 是二进制注释,用于标识文件为 PDF 格式

1.2 文件体(Body)

文件体包含文档的所有内容,由一系列对象组成。

1 0 obj
<<
  /Type /Catalog
  /Pages 2 0 R
>>
endobj

2 0 obj
<<
  /Type /Pages
  /Kids [3 0 R]
  /Count 1
>>
endobj

📝 要点

  • 每个对象都有唯一的编号和生成号
  • 对象之间通过引用相互关联
  • 对象可以是字典、数组、流等类型

1.3 交叉引用表(Cross-reference Table)

交叉引用表记录所有对象的位置,用于快速定位对象。

xref
0 6
0000000000 65535 f
0000000010 00000 n
0000000056 00000 n
0000000112 00000 n
0000000204 00000 n
0000000256 00000 n

🔍 解析

  • 第一行 0 6 表示从对象 0 开始,共 6 个条目
  • 每行包含:
    • 对象在文件中的偏移量(10位数字)
    • 生成号(5位数字)
    • 状态标记(n 表示使用中,f 表示空闲)
  • 例如 0000000010 00000 n 表示对象 1 在文件偏移量 10 处

1.4 文件尾(Trailer)

文件尾包含文档的根对象引用和文件结束标记。

trailer
<<
  /Size 6
  /Root 1 0 R
>>
startxref
320
%%EOF

📌 关键字段

  • /Size 指定交叉引用表中的条目数
  • /Root 指向文档的根对象(通常是目录对象)
  • startxref 指定交叉引用表的起始位置
  • %%EOF 是文件结束标记

1.5 完整示例

下面是一个完整的 PDF 文件结构示例:

%PDF-1.7
%¥±ë

1 0 obj
<<
  /Type /Catalog
  /Pages 2 0 R
>>
endobj

2 0 obj
<<
  /Type /Pages
  /Kids [3 0 R]
  /Count 1
>>
endobj

3 0 obj
<<
  /Type /Page
  /Parent 2 0 R
  /Resources <<
    /Font <<
      /F1 4 0 R
    >>
  >>
  /Contents 5 0 R
  /MediaBox [0 0 595 842]
>>
endobj

4 0 obj
<<
  /Type /Font
  /Subtype /Type1
  /BaseFont /Helvetica
  /Encoding /WinAnsiEncoding
>>
endobj

5 0 obj
<<
  /Length 100
>>
stream
BT
/F1 12 Tf
100 700 Td
(Hello World) Tj
ET
endstream
endobj

xref
0 6
0000000000 65535 f
0000000010 00000 n
0000000056 00000 n
0000000112 00000 n
0000000204 00000 n
0000000256 00000 n

trailer
<<
  /Size 6
  /Root 1 0 R
>>
startxref
320
%%EOF

🌟 示例说明: 这个示例展示了一个简单的 PDF 文件结构:

  1. 文件头声明 PDF 版本
  2. 文件体包含 5 个对象:
    • 目录对象(Catalog)
    • 页面树对象(Pages)
    • 页面对象(Page)
    • 字体对象(Font)
    • 内容流对象(Content Stream)
  3. 交叉引用表记录所有对象的位置
  4. 文件尾包含文档的根对象引用和交叉引用表位置

2. PDF 基本数据类型

PDF 支持多种基本数据类型,每种类型都有其特定的语法和用途。

2.1 布尔值(Boolean)

布尔值表示真或假。

/NeedAppearances true

2.2 数字(Number)

数字可以是整数或实数。

/Width 595.28

2.3 字符串(String)

字符串用括号括起来,支持转义字符。

(Hello World)
(Hello\nWorld)  # 包含换行符

2.4 名称(Name)

名称以 / 开头,用于标识对象。

/Type /Font
/#20#20  # 表示两个空格

2.5 数组(Array)

数组用方括号括起来,可以包含不同类型的元素。

[1 2 3]
[1 (text) /Name]  # 混合类型数组

2.6 字典(Dictionary)

字典用双尖括号括起来,包含键值对。

<<
  /Type /Page
  /Parent 2 0 R
  /Resources <<
    /Font <<
      /F1 3 0 R
    >>
  >>
  /MediaBox [0 0 595 842]
>>

2.7 流(Stream)

流包含二进制数据,通常用于存储图像、字体等。

<<
  /Length 100
  /Filter /FlateDecode
>>
stream
...二进制数据...
endstream

3. PDF 对象引用

PDF 使用对象引用来建立对象之间的关系。

1 0 obj
<<
  /Type /Catalog
  /Pages 2 0 R
>>
endobj

2 0 obj
<<
  /Type /Pages
  /Kids [3 0 R]
  /Count 1
>>
endobj

📝 格式说明

  • 格式:对象编号 生成号 R
  • 示例:2 0 R 表示编号为 2,生成号为 0 的对象

4. 常用 PDF 对象类型

4.1 页面对象(Page)

页面对象定义页面的内容和属性。

3 0 obj
<<
  /Type /Page
  /Parent 2 0 R
  /Resources <<
    /Font <<
      /F1 4 0 R
    >>
  >>
  /Contents 5 0 R
  /MediaBox [0 0 595 842]
>>
endobj

4.2 内容流(Content Stream)

内容流包含页面的实际内容。

5 0 obj
<<
  /Length 100
>>
stream
BT
/F1 12 Tf
100 700 Td
(Hello World) Tj
ET
endstream
endobj

4.3 字体对象(Font)

字体对象定义文本使用的字体。

4 0 obj
<<
  /Type /Font
  /Subtype /Type1
  /BaseFont /Helvetica
  /Encoding /WinAnsiEncoding
>>
endobj

4.4 图像对象(Image)

图像对象存储图像数据。

6 0 obj
<<
  /Type /XObject
  /Subtype /Image
  /Width 100
  /Height 100
  /ColorSpace /DeviceRGB
  /BitsPerComponent 8
  /Filter /DCTDecode
>>
stream
...JPEG 图像数据...
endstream
endobj