PDF文件結(jié)構(gòu)詳解_第1頁
PDF文件結(jié)構(gòu)詳解_第2頁
PDF文件結(jié)構(gòu)詳解_第3頁
PDF文件結(jié)構(gòu)詳解_第4頁
PDF文件結(jié)構(gòu)詳解_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、PDF(PortableDocumentFormat,便攜式文檔結(jié)構(gòu))是一種很有用的文件格式,其最大的特點(diǎn)是平臺無關(guān)而且功能強(qiáng)大(支持文字/圖象/表單/鏈接/音樂/視頻等).做PDF的解析,首先要熟悉PDF文件的物理結(jié)構(gòu)和邏輯結(jié)構(gòu)。PDF文件物理結(jié)構(gòu)可分為以下幾塊:1.文件頭文件頭是PDF文件的第一行,格式如下:%PDF-1.4這是個(gè)固定格式,表示這個(gè)PDF文件遵循的PDF規(guī)范版本,目前PDF的生成工具,除了官方的acrobat,其他生成的以1.4版本的居多。對于做PDF開發(fā)來說,一個(gè)最簡單的原則就是生成PDF的時(shí)候盡量符合低版本規(guī)范,以保證大多數(shù)解析器能支持;解析PDF的時(shí)候盡量支持高版本的

2、規(guī)范,以保證支持大多數(shù)工具生成的PDF文件。從1.4版本以后,PDF文件的版本并不唯一的只是在這里表示了,可能后面會改寫(catalog的Version詞條),所以解析PDF的時(shí)候,如果這里的版本大于等于1.4,應(yīng)該再比較一下catalog里面的version,取其中高一點(diǎn)的版本。2 .對象集合這是一個(gè)PDF文件最重要的部分,文件中用到的所有對象,包括文本/圖象/音樂/視頻/字體/超連接/加密信息/文檔結(jié)構(gòu)信息等等,都在這里定義。格式如下:20obj.endobj一個(gè)對象的定義包含4個(gè)部分:前面的2是對象序號,其用來唯一標(biāo)記一個(gè)對象;0是生成號,按照PDF規(guī)范,如果一個(gè)PDF文件被修改,那這個(gè)

3、數(shù)字是累加的,它和對象序號一起標(biāo)記是原始對象還是修改后的對象,但是實(shí)際開發(fā)中,很少有用這種方式修改PDF的,都是重新編排對象號;obj和endobj是對象的定義范圍,可以抽象的理解為這就是一個(gè)左括號和右括號;省略號部分是PDF規(guī)定的任意合法對象(一共8種,見后面附A)??梢酝ㄟ^R關(guān)鍵字來引用任何一個(gè)對象,比如要引用上面的對象,可以使用20R,需要主意的是,R關(guān)鍵字不僅可以引用一個(gè)已經(jīng)定義的對象,還可以引用一個(gè)并不存在的對象,而且效果就和引用了一個(gè)空對象一樣。3 .交叉引用表交叉引用表是PDf文件內(nèi)部一種特殊的文件組織方式,可以很方便的根據(jù)對象號隨機(jī)訪問一個(gè)對象。其格式如下:xref010000

4、00000065535f4 1000000000900000n8 3000000007400000n000000012000000n000000017900000n其中,xref是開始標(biāo)志,表示以下為一個(gè)交叉引用表的內(nèi)容;每個(gè)交叉引用表又可以分為若干個(gè)子段,每個(gè)子段的第一行是兩個(gè)數(shù)字,第一個(gè)是對象起始號,后面是連續(xù)的對象個(gè)數(shù),接著每行是這個(gè)子段的每個(gè)對象的具體信息一一每行的前10個(gè)數(shù)字代表這個(gè)這個(gè)對象相對文件頭的偏移地址,后面的5位數(shù)字是生成號(用于標(biāo)記PDF的更新信息,和對象的生成號作用類似),最后一位f或n表示對象是否被使用(n表示使用,f表示被刪除或沒有用)。上面這個(gè)交叉引用表一共有3個(gè)

5、子段,分別有1個(gè),1個(gè),3個(gè)對象,第一個(gè)子段的對象不可用,其余子段對象可用。4.trailer:通過trailer可以快速的找到交叉引用表的位置,進(jìn)而可以精確定位每一個(gè)對象;還可以通過它本身的字典還可以獲取文件的一些全局信息(作者,關(guān)鍵字,標(biāo)題等),加密信息,等等。具體形式如下:trailer<<key1value1key2value2key3value3>>startxref553%EOFtrailer后面緊跟一個(gè)字典,包含若干鍵-值對。具體含義如下:鍵值類型值說明Size整形數(shù)字所有間接對象的個(gè)數(shù)。一個(gè)PDF文件,如果被更新過,則會有多個(gè)對象集合、交叉引用表、tra

6、iler,最后一個(gè)trailer的這個(gè)字段記錄了之前所有對象的個(gè)數(shù)。這個(gè)值必須是直接對象。Prev整形數(shù)字Root字典Encrypt字典Info字典ID數(shù)組當(dāng)文件有多個(gè)對象集合、交叉引用表和trailer時(shí),才會有這個(gè)鍵,它表示前一個(gè)相對于文件頭的偏移位置。這個(gè)值必須是直接對象。Catalog字典(文件的邏輯入口點(diǎn))的對象號。必須是間接對象。文檔被保護(hù)時(shí),會有這個(gè)字段,加密字典的對象號。存放文檔信息的字典,必須是間接對象。文件的IDstartxref:后面的數(shù)字表示最后一個(gè)交叉引用表相對于文件起始位置的偏移量。%EOF:文件結(jié)束符.一個(gè)PDF文件,都會有上面這樣的結(jié)構(gòu)(線性化優(yōu)化的PDF例外,

7、這個(gè)后面單獨(dú)說)c實(shí)際一個(gè)pdf文件是很復(fù)雜的,但是上面幾個(gè)部分是確定的,只能多不能少.了解了PDF文件的物理結(jié)構(gòu),就可以提取出一個(gè)一個(gè)的對象了.PDF中的對象有8種:1.booleam用關(guān)鍵字true或false表示,可以是array對象的一個(gè)元素,或dictionary對象的一個(gè)條目.也可以用在PostScript計(jì)算函數(shù)里面,做為if或ifesle的一個(gè)條件。2.numeric包括整形和實(shí)型,不支持非十進(jìn)制數(shù)字,不支持指數(shù)形式的數(shù)字.例:1)整數(shù)1234567+111-2范圍:正2的31次方-1到負(fù)的2的31次方2)實(shí)數(shù)12.30.8+6.3-4.01-3.+.03范圍:±3.

8、403X10的38次方土1.175X10的-38次方注意:如果整數(shù)超過表示范圍將轉(zhuǎn)化成實(shí)數(shù),如果實(shí)數(shù)超過范圍就出錯(cuò)了3.string由一系列0-255之間的字節(jié)組成,一個(gè)string總長度不能超過65535.string有以下兩種方式:1) 直接字串由0包含起來的一個(gè)字串,中間可以使用轉(zhuǎn)義符"/".例:(abc)表示abc(a/)表不'a/轉(zhuǎn)義符的定義如下:轉(zhuǎn)義字符含義/n換行/r回車/t水平制表符/b退格/f換頁(Formfeed(FF)/(左括號/)右括號/反斜杠/ddd八進(jìn)制形式的字符2) 十六進(jìn)制字串由<>包含起來的一個(gè)16進(jìn)制串,兩位表示一個(gè)字

9、符,不足兩位用0補(bǔ)齊例:< Aabb>表示AA和BB兩個(gè)字符< AAB>表示AA和B0兩個(gè)字符4.name由一個(gè)前導(dǎo)/和后面一系列字符組成,最大長度為127.和string不同白是,name是不可分割的和唯一的,不可分割就是說一個(gè)name對象就是一個(gè)原子,比如/name,不能說n就是這個(gè)name的一個(gè)元素;唯一就是指兩個(gè)相同的name一定代表同一個(gè)對象.從pdf1.2開始,除了ascii的0,別的都可以用一個(gè)#加兩個(gè)十六進(jìn)制的數(shù)字表示.例:/name表示name/name#20is表示nameis/name#200表示name05.array用口包含的一組對象,可以是任

10、何pdf對象(包才array),雖然pdf只支持一維array,但可以通過array的嵌套實(shí)現(xiàn)任意維數(shù)的array(但是一個(gè)array的元素不能超過8191)例:5493.14false(Ralph)/SomeName6,Dictionary用"<<"和">>"包含的若干組條目,每組條目都由key和value組成,其中key必須是name對象,并且一個(gè)dictionary內(nèi)的key是唯一的;value可以是任何pdf的合法對象(包括dictionary對象).例:< </Integeritem12/Stringitem

11、(astring)/Subdictionary< </Item10.4/Item2true/Lastitem(not!)/VeryLastitem(OK)>>>>7.stream由一個(gè)字典,和緊跟其后面的一組關(guān)鍵字stream和endstream以及這組關(guān)鍵字中間包含一系列字節(jié)組成,內(nèi)容和string很相似,但有區(qū)別:stream可以分幾次讀取,分開使用不同的部分,string必須作為一個(gè)整體一次全部讀取使用;string有長度限制,但stream卻沒有這個(gè)限制,一般較大的數(shù)據(jù)都用stream表示,需要注意的是,Stream必須是間接對象,并且stream的

12、字典必須是直接對象。從1.2規(guī)范以后,stream可以以外部文件形式存在,這種情況下,解析PDF的時(shí)候stream和endstream之間的內(nèi)容就被忽略掉。例:dictionarystreamdataendstreamstream字典中常用的字段如下:字段名類型值Length整形(必須)關(guān)鍵字stream和endstream之間的數(shù)據(jù)長度,endstream之前可能會有一個(gè)多余的EOL標(biāo)記,這個(gè)不計(jì)算在數(shù)據(jù)的長度中。Filter名字或數(shù)組DecodeParms字典或數(shù)組(可選)Stream的編碼算法名稱(列表)。如果有多個(gè),則數(shù)組中的編碼算法列表順序就是數(shù)據(jù)被編碼的順序。(可選)一個(gè)參數(shù)字典或

13、由參數(shù)字典組成的一個(gè)數(shù)組,供Filter使用。如果僅有一個(gè)Filter并且這個(gè)Filter需要參數(shù),除非這個(gè)Filter的所有參數(shù)都已經(jīng)給了默認(rèn)值,否則的話DecodeParms必須設(shè)置給Filter。如果有多個(gè)Filter,并且任意一個(gè)Filter使用了非默認(rèn)的參數(shù),DecodeParms必須是個(gè)數(shù)組,每個(gè)元素對應(yīng)一個(gè)Filter的參數(shù)列表(如果某個(gè)Filter無需參數(shù)或所有參數(shù)都有了默認(rèn)值,就用空對象代替)。如果沒有Filter需要參數(shù),或者所有Filter的參數(shù)都有默認(rèn)值,DecodeParms就被忽略了。F文件標(biāo)識FFilter名字或字典FDecodeParms字典或數(shù)組(可選)保存s

14、tream數(shù)據(jù)的文件。如果有這個(gè)字段,stream和endstream就被忽略,F(xiàn)Filter將會代替Filter,FDecodeParms將代替DecodeParms。Length字段還是表示stream和endstream之間數(shù)據(jù)的長度,但是通常此刻已經(jīng)沒有數(shù)據(jù)了,長度是0.(可選)和filter類似,針對外部文件。(可選)和DecodeParams類似,針對外部文件。8.NULL用null表示,代表空.如果一個(gè)key的值為null,則這個(gè)key可以被忽略;如果引用一個(gè)不存在的object則等價(jià)于引用一個(gè)空對象.例:(略)以上八種對象是按照對象內(nèi)涵來分的,如果按照對象的使用規(guī)則來說,對象又

15、分為間接對象和直接對象。間接對象是PDF中最常用的對象,如前面對象集合里面的,所有對象都是間接對象,在其他位置通過R關(guān)鍵字來引用,在交叉引用表里面都是通過間接對象來引用的。直接對象就更好理解了,上面的8種對象單獨(dú)出現(xiàn)的時(shí)候就叫直接對象。PDF文件結(jié)構(gòu)(二)邏輯結(jié)構(gòu)作者:bobob郵件:zxbbobob要解析一個(gè)PDF文件,首先要掌握PDF的物理結(jié)構(gòu),這是第一步。但是這個(gè)僅僅只是基礎(chǔ),更重要的是對PDF邏輯結(jié)構(gòu)白解析。PDF的邏輯大體上是一個(gè)樹狀結(jié)構(gòu),根節(jié)點(diǎn)是catalog字典,通過這里去解析頁、目錄、鏈接信息等等,在這里按照PDF的樹形結(jié)構(gòu),詳細(xì)討論一下整個(gè)文件的邏輯框架。一、catalog根

16、節(jié)點(diǎn)catalog是整個(gè)PDF邏輯結(jié)構(gòu)的根節(jié)點(diǎn),這個(gè)可以通過trailer的Root字段定位,雖然簡單,但是相當(dāng)重要,因?yàn)檫@里是PDF文件物理結(jié)構(gòu)和邏輯結(jié)構(gòu)的連接點(diǎn)。Catalog字典包含的信息非常多,這里僅就最主要的幾個(gè)字段做個(gè)說明。(1) Pages字段這是個(gè)必須字段,是PDF里面所有頁面的描述集合。Pages字段本身是個(gè)字典,它里面又包含了一下幾個(gè)主要字段:字段值Typename(必須)只能為Pages。Parentdictionar(如果不是catalog里面指定的跟節(jié)點(diǎn),則必須有,并且必須是間y接對象)當(dāng)前節(jié)點(diǎn)的直接父節(jié)點(diǎn)。Kidsarray(必須)一個(gè)間接對象組成的數(shù)組,節(jié)點(diǎn)可能是

17、page或pagetreeCountinteger(必須)pagetree里面所包含葉子ij點(diǎn)(page對象)的個(gè)數(shù)。從以上字段可以看出,Pages最主要的功能就是組織所有的page對象。Page對象描述(可選;可繼承)順時(shí)鐘旋轉(zhuǎn)的角度數(shù),這個(gè)必須是90的整數(shù)倍,默認(rèn)是0。了一個(gè)PDF頁面的屬性、資源等信息。Page對象是一個(gè)字典,它主要包含一下幾個(gè)重要的屬性:字段回值Typename(必須)必須是Page。Parentdictionary(必須;并且只能是間接對象)當(dāng)前page節(jié)點(diǎn)的直接父節(jié)點(diǎn)pagetree。LastModifieddate(如果存在PieceInfo字段,就必須有,否則可

18、選)記錄當(dāng)前頁面被最已-次修改的日期和時(shí)間。Resourcesdictionary(必須;可繼承)記錄了當(dāng)前page用到的所有資源。如果當(dāng)前頁不用任何資源,則這是個(gè)空字典。忽略所有字段則表示繼承父節(jié)點(diǎn)的資源。MediaBoxrectangle(必須;可繼承)定義了要顯本或打印頁面的物埋媒介的區(qū)域(defaultuserspaceunits)CropBoxrectangle(可選;可繼承)定義了一個(gè)可視區(qū)域,當(dāng)前頁被顯示或打印的時(shí)候,它的內(nèi)容會被這個(gè)區(qū)域裁剪。默認(rèn)值就是MediaBox。BleedBoxrectangle(可選)定義了一個(gè)區(qū)域,當(dāng)輸出設(shè)備是個(gè)生產(chǎn)環(huán)境(productionenvi

19、ronment)的時(shí)候,蟲面顯布的內(nèi)容會被裁剪。默認(rèn)值是CropBox.Contentsstreamorarray(可選)描述頁面內(nèi)容的流。如果這個(gè)字段缺省,則頁面上什么也不會顯示。這個(gè)值可以是一個(gè)流,也可以是由幾個(gè)流組成的一個(gè)數(shù)組。如果是數(shù)組,實(shí)際效果相當(dāng)于所有的流是按順序連在一起的一個(gè)流,這就允許PDF生成的時(shí)候可以隨時(shí)插入圖片或其他資源。流之間的分割只是詞匯上的一個(gè)分害U,并不是邏輯上或者組織形式的切割。RotateintegerThumbstream(可選)定義當(dāng)前頁的縮略圖。Annotsarray(可選)和當(dāng)前貝囿美聯(lián)的注釋。Metadatastream(可選)當(dāng)前頁包含的元數(shù)據(jù)。一

20、個(gè)簡單例子:30obj<</Type/Page/Parent40R/MediaBox00612792/Resources<</Font<</F370R/F590R/F7110R>>/ProcSet/PDF>>/Contents120R/Thumb140R/Annots230R240R>>endobj(2) Outlines字段Outline是PDF里面為了方便用戶從PDF的一部分跳轉(zhuǎn)到另外一部分而設(shè)計(jì)的,有時(shí)候也叫書簽(Bookmark),它是一個(gè)樹狀結(jié)本勾,可以直觀的把PDF文件結(jié)構(gòu)展現(xiàn)給用戶。用戶可以通過鼠標(biāo)點(diǎn)擊來打開

21、或者關(guān)閉某個(gè)outline項(xiàng)來實(shí)現(xiàn)交互,當(dāng)打開一個(gè)outline時(shí),用戶可以看到它的所有子節(jié)點(diǎn),關(guān)閉一個(gè)outline的時(shí)候,這個(gè)outline的所有子節(jié)點(diǎn)會自動隱藏。并且,在點(diǎn)擊的時(shí)候,閱讀器會自動跳轉(zhuǎn)到outline對應(yīng)的頁面位置。Outlines包含一下幾個(gè)字段:KEYTYPEVALUETypename(可選)如果這個(gè)字段有值,則必須是Outlines。Firstdictionary(必須;必須是間接對象)簾-個(gè)頂層OutlineitemLastdictionary(必須;必須是間接對象)取后個(gè)頂層outlineitemCountinteger(必須)outline的所啟層次的item的

22、總數(shù)。Outline是一個(gè)管理outlineitem的頂層對象,我們看到的,其實(shí)是outlineitem這個(gè)里面才包含了文字、行為、目標(biāo)區(qū)域等等。一個(gè)outlineitem主要有一下幾個(gè)字段:Titletextstring(必須)當(dāng)前item要顯示的標(biāo)題。Parentdictionary(必須;必須是間接對象)outline層級中,當(dāng)前item象。如果item本身是頂級item,則父對象就是它本身。的父對Prevdictionary(除了每層的令-個(gè)item外,其他item必須有這個(gè)子1是間接對象)當(dāng)前層級中,此item的前一個(gè)item。乏;必須Nextdictionary(除了每層的最舟-個(gè)

23、item外,其他item必須有這個(gè)字段;必須是間接對象)當(dāng)前層級中,此item的舟-個(gè)item。Firstdictionary(如果當(dāng)前item有任何子節(jié)點(diǎn),則這個(gè)字段是必須的間接對象)當(dāng)前item的A個(gè)直接于節(jié)點(diǎn)。;必須是Lastdictionary(如果當(dāng)前item有任何子節(jié)點(diǎn),則這個(gè)字段是必須的間接對象)當(dāng)前item的最舟-個(gè)直接子節(jié)點(diǎn)。;必須是Destname,bytestring,orarray(可選;如果A字段存在,則這個(gè)不能被會略)當(dāng)前的item被激活的時(shí)候,要顯示的區(qū)域。outlinedictionary(可選;如果Dest字段存在,則這個(gè)不能被忽略)當(dāng)前的outlineite

24、m被激活的時(shí)候,要執(zhí)行的動作。(3) URI字段URI(uniformresourceidentifier),定義了文檔級別的統(tǒng)一資源標(biāo)識符和相關(guān)鏈接信息。目錄和文檔中的鏈接就是通過這個(gè)字段來處理的。(4) Metadata字段文檔的一些附帶信息,用xml表示,符合adobe的xmp規(guī)范。這個(gè)可以方便程序不用解析整個(gè)文件就能獲得文件的大致信息。(5) 其他Catalog字典中,常用的字段一般有以下一些:字段回值Typename(必須)必須為Catalog。Versionname(可選)PDF文件所遵循的版本號(如果比文件頭指定的版本號高的話)。如果這個(gè)字段缺省或者文件頭指定的版本比這里的高,那就以文件頭為準(zhǔn)。一個(gè)PDF生成程序可以通過更新這個(gè)字段的值來修改PDF文件版本號。Pagesdictionary(必須并且必須為間接對象)當(dāng)前文檔的頁面集合入口。PageLabelsnumbertree(可選)numbertree,定義了貝囿和貝囿label對應(yīng)關(guān)系。Namesdictionary(可選)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論