PDF文件格式的一些研究心得

现在让我简要介绍一下PDF的文件格式,PDF的文件格式说明,最权威的就是Adobe官方网上的PDFReference,纯英文版的,一千多页,个人认为对于国内的开发者做PDF的生成的时候,最大的困难就在这里了,一个是没有充足的时间去看,二个一看满篇的英文基本上就头大。我只看了三分之一左右,看了整体描述和有针对性地看了一些,必竟HTML转PDF的时候,有不少的东西是用不着的。现在我介绍一下PDF格式的一些要点:
一、PDF文件是一种文本和二进制混排的格式,但是Adobe更愿意让人把它当成二进制的文件,所以在里面建议当文件里面的文本太多的时候,可以加一些二进制的注释,好让现有的一些编译器把它当成二进制文件。里面的文本主要是对文件结构的一种描述,二进制的内容来自于三个方面:1、图片;2、字体;3、压缩后的Post Script。
二、文件结构可以分为三方面:
1、首部。用文本编辑器打开的时候就可以看到:%PDF-1.4 这样的字眼,其中最后一位就是PDF文件格式版本号,软件的版本号总要比文件格式的版本号高1,比如说Read 5能打开的内容就是4。
2、文件体。里面有若干个的obj,以及xref来组成,OBJ这种形式:
30979 0 obj
<<
/Linearized 1
/O 30982
/H [ 15061 25084 ]
/L 9379963
/E 166967
/N 978
/T 8760262
>>
endobj 
第一个数字就是这个OBJ的顺序号,是为了便于在xref中查找,后面的0是为了区分不同的OBJ,现在都是0(个人感觉是为了以后扩展用的)后面就是关键字obj.下面的各行就是属性,/关键字 值 的形式。
xref是obj的索引表,用来索引各个obj在文档中的起始位置,它的形式是:
xref
0 211
0000000000 65535 f
0000000009 00000 n
……
0000087999 00000 n

trailer
<<
/Size 211
/Root 2 0 R
/Info 1 0 R
/ID [<B29FBB52459C4623DB1A90CBFC28381E><B29FBB52459C4623DB1A90CBFC28381E>]
>>
其中0,211分别代表这个xref的obj的起始和终止序号。其中0这个是估计是为了程序中好处理所以加了这个(个人英文水平不行,有些地方看不明白),可以不加入这个。下面的各行就代表各个obj在这个文档的起始位置,其中第一串字符(10个)代表起始位置,中间的五个字符也是为了区分用的,现在基本上全为0, 后面的字母有两种f代表删除的,n代表要使用的。后面的trailer是对整个xref的摘要,说明里面有多少个OBJ,读的时候从哪个OBJ开始解析,信息节点等,ID是为了让一些文件检索工具能够唯一区分文件。
3、文件尾。
startxref
88019
%%EOF
因为一个文档中可以有多个xref,所以这里要指明要从哪个xref开始进行解析这个文件。
从上面的分析来看:PDF文件内部校验是很复杂的,只要里面有一位错位了,就会导致整个文档读取错误。而且它时硕会有不少的二进制内容,所以一般来说在内存里面存储的时候,用流对象,而不能用字串,特别是生成的时候,每加入一个obj的时候,去获取一下当前流的长度就可以得到每个obj的起始位置,同时把获取的这些位置存到ArrayList里面,这样就可以很方便地得到和内容相一致的xref了。
三、PDF里面对象的组成形式,可以说是用树形结构来相互关联的,驵下面挂页集合,页集合下面挂页,页里挂图片,链接,内容等
四、PDF里面的obj的类型主要有以下几种:
1、文件描述对象,用来描述这个文件的标题,作者,时间等
2、组对象,也就是文档内容的起始结点。Type 为Catalog
3、页集合,里面聚合了大量的页对象。  Type 为pages
4、页对象,里面指明了当前页里面用到的字体,内容,活动对象,图片等。Type 为page
5、活动对象,有链接,文字,声音,电影等,Type 为Annots
6、图片对象, Type 为 XObject
7、字体对象,Type 为 Font 。PDF可以内置字体,所以即使目标机器上没有,只要它内置了,也可以正常地显示,不受影响(内置字体,这个我还没有研究清楚,希望知道的人可以告诉我一下,这里先谢了)
8、流对象。所有的二进制内容都是存在这个对象里面,文件流的常见的压缩方式是:图片的一些压缩算法,FlateDecode,ASCIIHexDecode,ASCII85Decode等等,FlateDecode事实上就是ZIP的压缩算法(关这个,我就花了好长的时间去研究)。流对象的长度是关连到一个长度对象上的/Length  188 0 R这种形式。188就是存这个长度的OBJ的顺序号。
9、数字对象。
188 0 obj
2538
endobj
里面只有一个数字,经常用来表示长度,为什么要把长度还要再用对象来表示,这个到现在我也想不太明白。
以上就是我对PDF文件格式的理解的摘要。也许有些地方可能理解得不正确,希望得到大家的指正。

posted on 2006-01-05 13:06  铁匠  阅读(13140)  评论(6编辑  收藏  举报