应该项目需要,初步研究了一下
PDF
的格式,打算和大家分享一下,如果有想做
PDF
或
PDF
阅读器开发的同学们,可以看看。
PDF
格式规范,语法简洁。但初次查看
PDF
却容易给人错觉
——PDF
的二进制流太多了,原本清晰的数据格式被杂乱无章的二进制流给淹没了。
例如:
stream
5di?倯? 貓?匚{o绝幾Te:馎HG
嵶?W}?妮雥??隱q?屸鷭鴊狳!赭€?鼜 ??烖K柽z煜?w? ??鴚¬D¬h?斜?醱釓?x?i佲匃???灗 Iu叁剪?
…………………………
<!----><!---->
<!---->
像这样一大堆乱码的东西很多,所以,心理上无法耐心的继续看下去。
实际上
PDF
就是由四部分组成:
<!----><!---->
<!---->
数据流的读写操作一般是从文件末尾开始的:
<!----><!----><!---->
<!---->
PDF
所有的数据类型都是
obj
,强调的也是一切皆对象。我简要的把
PDF
常见的几种数据类型给大家说说:
注意“
%
”表示注释
<!---->1.
<!---->Boolean Objects
:只有
true
和
false
<!---->2.
<!---->Numeric Objects
:
<!---->l
<!---->整型:
123
<!---->l
<!---->浮点型
-43.54
,
6.02E23
3.
String
Objects
:
<!---->l
<!---->文字型,用圆括号括起来,如:
(Hello World)
<!---->l
<!---->十六进制型,用尖括号括起来,如:
<901FA3>
分别为
90
,
1F
,
A3
4.
Name Objects
:除
null
以外的任意
8
位字符组成的字符串,出现在
PDF
中,用“
/
”作前导符号,如:
/Name1
。其实这与编程中的常量很类似。
5.
Array
Objects
:
PDF
中的数组用方括号“
[]
”括起来,里面的数据可以完全不相同,如:
[549 3.14 false
(Ralph) /SomeName]
该数组里面分别装有
5
种不同的类型。
<!---->6.
<!---->Dictionary Objects
:其实就类似于
Java
的
Map
对象——即以
key
,
value
的形式成对出现。用的时候要用“
<<…>>
”把
key
,
value
括起来。例如:
<</Name
(leo) >>
表示
key
为“
name
”的
Name
Objects
,而
value
为“
leo
”字符串。
<<>>
内部也可以嵌套使用,在
PDF
源文件中应用的非常广泛。
<!---->7.
<!---->Stream Objects
:顾名思义,肯定有流有关。这就是
PDF
中专门用于存放二进行流的对象。
PDF
的实现者对
String Objects
通常会做限制,但是
Stream Objects
却没有这样的限制。因此
stream object
用在图片,页面描述信息上是非常的适合的。
<!---->
看看使用示例:
7 0 obj %某一个Image类型的对象
<<
/Type /XObject
/Subtype /Image
/Name /Im7
/Width 189
/Height 189
/BitsPerComponent 8
/ColorSpace [/Indexed /DeviceRGB 255 …>]
/Mask [255 255]
/Length 3832
/Filter /FlateDecode
>> %紧接着这个对象定义后的Dictionary Objects对象后面
stream %定义它的Stream Objects
%这里放二进制流
endstream
<!----><!---->
<!---->
<!---->8.
<!---->Null Object
:区别与其它任何对象,用关键字
null
标注的对象就是
null object
。
<!---->9.
<!---->Indirect Objects
:当然就是类似
Java
中的“引用”概念啦,举个例子就说明一切了。
7 0 obj %有一个索引号为7 0的对象
<< /Length 8 0 R >> % 在它的Length属性引用了一个索引号为8 0的对象
%在这里“8 0 R”表示对8 0的对象引用(Reference)
stream
………….
endstream
endobj
8 0 obj %被上面7 0对象所引用的那个索引号为8 0的对象
77 %7 0对象的二进制流的长度
endobj
注意:
<!---->obj …… endobj PDF
文档组成的最小
组成部分。表示一个完整对象的定义
<!----><!---->
<!---->
够了,说了这么多,让我们实战吧。现在我们来看一个完整的示例,该示例可以在附件中下载。看的时候,可以按照下面的步骤一步一步来分析
PDF
源文件:
%PDF-1.3
%
2 0 obj %2 0 obj,里面是一些PDF的基本信息。比如
<<
/CreationDate (D:20081029093606+08'00') %创建时间
/ModDate (D:20081029093606+08'00') %最后修改时间
/Producer (leo 4.30 \(0615\)) %创建人
/Creator (easyPDF SDK 4.3) %制作人
>> %你还可以自由的编写任何信息
endobj
1 0 obj
<<
/Count 0
>>
endobj
3 0 obj %这是PDF的根结点(不是起始位置)
<<
/Type /Catalog
/Pages 4 0 R %这是所有页面的集合,我们主要关心这个
/Outlines 1 0 R
>>
endobj
7 0 obj
<<
/Type /XObject
/Subtype /Image
/Name /Im7
/Width 189
/Height 189
/BitsPerComponent 8
/ColorSpace [/Indexed /DeviceRGB 255 <%这里放每个像素点的值>]
/Mask [255 255]
/Length 3832
/Filter /FlateDecode
>>
stream
%这里放的全是图片的二进制流……..
endstream
endobj
8 0 obj
<<
/Length 51
/Filter /FlateDecode
>>
stream
%这里放的全是图片的二进制流……..
endstream
endobj
6 0 obj %重点分析一下这个
<<
/Type /Page
/Parent 4 0 R
/MediaBox [ 0 0 595.276 841.89 ]
/Resources <<
/XObject <<
/Im7 7 0 R
>>
/ProcSet [/PDF /Text /ImageB /ImageC] >>
/Contents 8 0 R
>>
endobj
4 0 obj
<<
/Type /Pages
/Kids [
6 0 R %继续查找6 0 obj来看看具体的页面情况
]
/Count 1
>>
endobj
xref %索引,f表示该地址未被使用,n表示已经被占用。
0 9 %索引的顺序与对象在文中出现的序号是一致的,比如
0000000000 65535 f %默认占位符,不使用。
0000000177 00000 n %表示0 1 obj的偏移地址
0000000015 00000 n %表示0 2 obj的偏移地地 下面的以些类推
0000000208 00000 n
0000006159 00000 n
0000000000 00000 n %表示0 5 obj的偏移为0,可能被删除操作给干掉了。
0000005981 00000 n
0000000274 00000 n
0000005858 00000 n
trailer
<<
/Size 9
/Root 3 0 R %这个属性信息最重要,我们可以直接找到根结点
/Info 2 0 R
/ID[<112cbcc8320742d1cbe148d4ec0d7dba><112cbcc8320742d1cbe148d4ec0d7dba>]
>>
startxref %PDF文件解析的起点
6219
%%EOF
<!----><!---->
<!---->
第一步:
首先是先看文件末尾,找到它的“
xref
”和“
trailer
”部分。
Xref
表示对象索引,其实就是对象在文件中的偏移地址(
PDF
源文件中是以
10
进制表示的,你转换成
16
进制后,用
UE
或者其它工具查看即可)
。
Trailer
虽然从字面上看是“尾部”的意思,但是解析却从它开始。“
startxref
”表示文件的入口地址,像
java
的
main()
方法。后面紧跟着一个
10
进制的数字,指向的是索引“
xref
”的位置。
Trailer
里面的值分别表示:
<!---->1.
<!---->Size 9
:表示
9
个索引值
<!---->2.
<!---->Root 3 0 R
:根结点是
3 0 obj
的引用
<!---->3.
<!---->Info 2 0 R
:相关信息是
2 0 obj
的引用
<!---->4.
<!---->ID
:类似于
Java
的
Serializable
机制,给本
PDF
文件生成一个独一无二的标识
第二步:
按照
Root 3 0 R
,我们向上查找,找到了我们要找的
Root
对象,里面的信息从字面上很容易理解:
<!---->1.
<!---->/Type /Catalog
:表示该对象的类型是目录
<!---->2.
<!---->/Pages 4 0 R
:表示所有的
PDF
页面在一个叫
4 0 R
的对象上
<!---->3.
<!---->/Outlines 1 0 R
:
PDF
文件的大纲,也就是左侧展示的东西。
继续查找
4 0 obj
,果然与预期所想的一样,的确是所有页面的集合,并且还有一个附加属性
Count
统计页面对象的个数:
/Type /Pages
:表示该对象的类型是所有页面的集合
/Kids […]
:这是一个数组,里面装的是每个页面的具体引用。因为这个
PDF
就一页,所有只有一个“
6 0
R
”。下一步,就从这里入手。
/Count 1
:页的总数大小,因为这个
PDF
就一页,所以值为
1
。编程时可能会用到。
第三步:
来重点分析一下页对象
6 0 obj %索引编号为6的对象,0表示该对象的修改次数
<< % << 表示是这一个map,里面的所有数据都以key,value形式出现
/Type /Page %其类型为Page,表示PDF的每一页
/Parent 4 0 R %其父结点为4 0对象(R表示引用,对象之间是可以双向引用的)
/MediaBox [ 0 0 595.276 841.89 ] %当前页画布为MediaBox样式,后面的表示左上角与右下角坐标,这样就形成了一个矩形。
/Resources << % Resources 又为一个map的嵌套
/XObject << % XObject 也是一个map的嵌套
/Im7 7 0 R % 在Xobject中定义了一个叫Im7的名称,引用了叫Im7的7 0对象(在我的PDF中,这是一个图片对象)
>>
/ProcSet [/PDF /Text /ImageB /ImageC] >> % 打印时的参数设置
/Contents 8 0 R % 这里是实际页面上的内容信息,引用的是8 0对象
>>
endobj % 对象定义结束
<!----><!---->
<!---->
对于我们来说,以下是项目开发的重点。因为要实现
PDF
文件盖章的添加或删除功能,必须进行流操作,并且图片在
PDF
文件的位置也要写入。
<!---->l
<!---->/XObject<<>>
:
里面持有图片等二进制的引用。通过上述的方法,当你再查看
7 0 obj
时,就会看到大量的二进制文件了。
<!---->l
<!---->/Contents
:
是文件的内容信息。比如说,页面上的文本,图片的坐标位置等。
通过这个完整的流程,你应该明白
PDF
的格式其实就是一个层次分明的树形结构。不过,想完全了解
PDF
的格式,进行相关的操作。你还得参看
PDF
规范文档。
分享到:
相关推荐
Java操作word转PDF需要下载Jacob包.
标题提到的"打开PDF文件labview源文件"指的是使用LabVIEW来处理与PDF相关的操作,可能是读取、解析或者生成PDF文档。在LabVIEW中,可以通过编写VI(Virtual Instrument,虚拟仪器)程序来实现这些功能。 LabVIEW的....
在深入使用这些源文件之前,理解PDF417条码的编码规范和解码过程是很有帮助的。PDF417条码由多个模块组成,每个模块可表示7位二进制数据。编码过程涉及将ASCII字符转换为二进制,分配校验位,以及将数据和校验位分割...
《Spine_2D骨骼新手动画教程》是一个专为初学者设计的教程资源包,包含了详细的PDF教程和实例源文件,旨在帮助用户快速掌握2D骨骼动画的制作技巧。在这个教程中,你将深入理解Spine工具的强大功能,并学习如何通过它...
FLUENT 2020R2 tutorial guide PDF及案例源文件 1.What’s In This Manual The ANSYS Fluent Tutorial Guide contains a number of tutorials that teach you how to use ANSYS Flu- ent to solve different types ...
在某些情况下,可能需要将DB数据块转换为源文件,或者反过来,从源文件生成DB。以下将详细解释这两个过程。 1. 从DB数据块生成源文件 - **步骤1:创建DB块** 首先,你需要在TIA博途V17的工作环境中创建一个新的DB...
Flash源文件下载包含了一系列的.swf文件,这些文件是Adobe Flash Professional创作的动画或交互式内容的二进制格式。SWF(ShockWave Flash)是Adobe Flash Player支持的格式,广泛用于网页上的动画、游戏、视频和...
1.类名是"PdfPageCount",位于名字控件"PdfPageCounter"下。作用是快速提取页面数目。 2.PdfPageCount类需要添加zlib依赖。 3.已经集成到MSVC工程,可以直接运行。提供命令行工具。工程中包含测试函数。
为Adobe Reader添加书签功能,一直用Adobe Reader看pdf文档,但是发现它竟然没有书签功能。导致每次打开文档后都要从第一页往后翻。。。。于是google了一下,发现了两种解决方法。 1. Reader本身提供了一个记忆上次...
1. 此源文件是免费提供,故不提供技术支持或修改服务,如果对免费的源文件不满意可以联系我们定做动画或低价购买成片。 2. 提供的源文件一般由Flash 8.0或者Flash CS4这两个版本创建,如果需要自行编辑,请先到这里...
maya房建模下载源文件maya房建模下载源文件maya房建模下载源文件maya房建模下载源文件maya房建模下载源文件maya房建模下载源文件maya房建模下载源文件
ASM2模型源文件.pdf
html动漫网站毕业设计含源文件).pdfhtml动漫网站毕业设计含源文件).pdfhtml动漫网站毕业设计含源文件).pdfhtml动漫网站毕业设计含源文件).pdfhtml动漫网站毕业设计含源文件).pdfhtml动漫网站毕业设计含源文件).pdf...
MAYA人物行走动画源文件(动画)MAYA人物行走动画源文件(动画)MAYA人物行走动画源文件(动画)MAYA人物行走动画源文件(动画)MAYA人物行走动画源文件(动画)
php源文件php验证码php验证码源文件,最近刚写的php验证码源文件!
"漂亮的商业PS源文件"指的是使用Photoshop创作的高质量、适用于商业用途的设计模板或素材。这些源文件通常包含分层的PSD格式,允许设计师在需要时进行修改和定制,以适应不同的商业需求。 源文件的重要性在于它们...
室外配套设施工程监理规划.pdf
在3D室内设计领域,源文件是至关重要的资源,它包含了设计项目的全部细节和设置,使得设计师能够对设计进行编辑、调整和优化。本压缩包提供的"3D室内设计源文件"是一个专注于单间室内设计的项目,简洁而实用,为用户...