宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

概述
PDF是一种不依赖应用程序软件、硬件和操作系统的文件格式。
PDF页包含文本、图形和图像。页面外观由内容流(content stream)描述,内容流包含一些列图形对象(graphics objects)。
PDF支持不同注释,有文本注释、超链接、标签、文件附件、声音及影视。
PDF包含高级信息,这些信息可用来与其他应用程序进行内容交互。

PDF的核心是它描述复杂图形和排版的能力。该能力是通过Adobe imaging model实现的。
PDF可作为一种页面描述语言,该语言是通过图像模型来描述页面的图形外观。
标准的图形对象有:path对象、text对象、image对象。
PDF文件可以说成是8位二进制字节序列。是二进制文件。它支持业界压缩标准,带有字体管理功能。
PDF文件能够加密,通过授权才能使用。它还能够通过数字签名来授权。
PDF与PostScript的不同:
PDF有严格的文档结构,此文档结构使应用程序可以以任何顺序访问文档中不同部分。
为简化内容流过程,PDF没有象函数、变量及控制结构这些编程语言的特点。
PDF包含有字体内容以保证高保真。
PDF有可能还含有其他与成像模型无直接关系的内容,如超链接、内容交互的逻辑信息。

结构
PDF(Portable Document Format,便携式文档结构)是一种很有用的文件格式,与平台无关。PDF文档是通过一系列对象序列来构造的,PDF对象包括直接对象(Direct Object)和间接对象(Indirect Object)。间接对象是经过标识了的PDF对象,直接对象通常有布尔型(Boolean)、数值型(Number)、字符串型(String)、名字型(Name)、数组型(Array)、字典型(Dictionary)、空对象(Null)、流对象(Stream)等基本类型。
一个PDF文档包含了一个或多个页面,而每一页都可以包含文档、图形和图像。一个典型的PDF文件结构可分4块:文件头、文件主体、交叉引用表和文件尾追踪器。
文件头(Header)位于PDF文档的第一行,它表明了当前文件所使用PDF规范的版本;文件体(Body)中包括构成文件间接对象的一个序列,这些对象代表了文档中的各个组件,例如字体、页树和图像等等;交叉引用表(Cross-reference Table)则是为了能对间接对象进行随机存取而设立的一个间接对象地址索引表,它给出了所有当前文件使用对象的入口地址,即字节偏移量,以便系统随机访问不同的对象;文件尾追踪器(Trailer)中包含了交叉引用表的起始地址和其中的对象总数、文档中Catalog(目录)对象的对象号以及加密等安全信息,根据文件尾提供的信息PDF的应用程序可以找到交叉引用表和整个PDF文件的目录对象,从而控制整个PDF文档。

1.header:
pdf文件的第一行,格式如下:
%PDF-1.7
表示当前文件的版本是1.7(目前最高版本为1.7)。

2.body:
pdf文件中用到的所有对象,包括文本图象音乐视频字体超连接加密信息等等,格式如下:

2 0 obj

end obj

其中省略号部分是pdf规定的任意合法对象(一共8种)。

3.cross reference table:
所有pdf对象的引用表,其格式如下:

xref
0 5
0000000000 65535 f
0000000009 00000 n
0000000074 00000 n
0000000120 00000 n
0000000179 00000 n

其中,xref是开始标志,表示以下为引用表内容;0 5表示从对象号为0的开始,连续有5个对象(0,1,2,3,4),分别用5行来表示。每行的前10个数字代表这个对象相对文件头的偏移地址,后面5个数字只有当这个对象被删除的时候才有用,表示这个对象被删除后又被重新生成后的对象号;最后一位f或n表
示对象是否被使用(n表示使用,f表示被删除或没有用)。

4.trailer:
整个pdf文件的入口点,形式如下:
trailer
<<
/Size 8
/Root 1 0 R
>>
startxref
553
%%EOF

/size:这个pdf中总共使用了多少个对象
/root:这个pdf文件的catalog对象的对象号,这是pdf中最顶层的对象
/startxref:后面的数字表示最后一个cross reference table的开始位置
/%%EOF:文件结束符.

实际一个pdf文件是很复杂的,但是上面几个部分是确定的。

pdf8种对象类型
1.booleam
用关键字true或false表示,可以是array对象的一个元素,或dictionary对象的一个条目.

2.numeric
包括整形和实型,不支持非十进制数字,不支持指数形式的数字.

例:
1)整数123 4567 +111 -2
范围:正2的31次方-1到负的2的31次方
2)实数12.3 0.8 +6.3 -4.01 -3. +.03
范围:±3.403 × 10的38次方 ±1.175 × 10的-38次方
注意:如果整数超过表示范围将转化成实数,如果实数超过范围就出错了

3.string
由一系列0-255之间的字节组成,一个string总长度不能超过65535.string有以下两种方式:
1)由()包含起来的一个字串,中间可以使用转义符””.
例:
(abc)表示abc
(a\)表示a
2)由<>包含起来的一个16进制串,两位表示一个字符,不足两位用0补齐
例:
<Aabb>表示AA和BB两个字符
<AAB>表示AA和B0两个字符

4.name
由一个前导/和后面一系列字符组成,最大长度为127.和string不同的是,name是不可分割的和唯一的,不可分割就是说一个name对象就是一个原子,比如/name,不能说n就是这个name的一个元素;唯一就是指两个相同的name一定代表同一个对象.从pdf1.2开始,除了ascii的0,别的都可以用一个#加两个十六进制的数字表示.
例:
/name表示name
/name#20is表示name is
/name#200表示name 0

5.array
用[]包含的一组对象,可以是任何pdf对象(包括array).虽然pdf只支持一维array,但可以通过array的嵌套实现任意维数的array(但是一个array的元素不能超过8191)
例:
[549 3.14 false (Ralph) /SomeName]

6.Dictionary
用”<<“和”>>”包含的若干组条目,每组条目都由key和value组成,其中key必须是name对象,并且一个dictionary内的key是唯一的;value可以是任何pdf的合法对象(包括dictionary对象).
例:
<< /IntegerItem 12
/StringItem (a string)
/Subdictionary << /Item1 0.4
/Item2 true
/LastItem (not!)
/VeryLastItem (OK)
>>
>>

7.stream
由关键字stream和endstream包含一系列字节.内容和string很相似,但有区别:stream可以分几次读取,分开使用不同的部分,string必须作为一个整体一次全部读取使用;string有长度限制,但stream却没有这个限制.一般较大的数据都用stream表示.
例:(略)

8.NULL
用null表示,代表空.如果一个key的值为null,则这个key可以被忽略;如果引用一个不存在的object则等价于引用一个空对象.
例:(略)

pdf不允许打印是因为pdf有自己的加密措施,限制打印。
找到trailer,如果这个pdf是加密的话会有一个/Encrypt的name,他的值一般形式是n 0 R,表示这个pdf文件的加密信息在n 0这个obj里面记录。找到这个obj,其下有一个/P的name,他的值是一个数字(32位),其中第三位代表是否有打印权限。

http://cinderella.zw.blog.163.com/blog/static/120242289201152913651544/