PDF文件結(jié)構(gòu)詳解之歐陽治創(chuàng)編_第1頁
PDF文件結(jié)構(gòu)詳解之歐陽治創(chuàng)編_第2頁
PDF文件結(jié)構(gòu)詳解之歐陽治創(chuàng)編_第3頁
PDF文件結(jié)構(gòu)詳解之歐陽治創(chuàng)編_第4頁
PDF文件結(jié)構(gòu)詳解之歐陽治創(chuàng)編_第5頁
已閱讀5頁,還剩15頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10PDF(PortableDocumentFormat,便攜式文檔結(jié)構(gòu))是一種很有用的文件格式,其最大的特點是平臺無關(guān)而且功能強大(支持文字/圖象/表單/鏈接/音樂/視頻等).做PDF的解析,首先要熟悉PDF文件的物理結(jié)構(gòu)和邏輯結(jié)構(gòu)。PDF文件物理結(jié)構(gòu)可分為以下幾塊:1.文件頭 文件頭是PDF文件的第一行,格式如下:時間2021.03.10創(chuàng)作:歐陽治%PDF-1.4歐陽治創(chuàng)編2021.03.10 歐陽治

創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10這是個固定格式,表示這個PDF文件遵循的PDF規(guī)范版本,目前PDF的生成工具,除了官方的acrobat,其他生成的以1.4版本的居多。對于做PDF開發(fā)來說,一個最簡單的原則就是生成PDF的時候盡量符合低版本規(guī)范,以保證大多數(shù)解析器能支持;解析PDF的時候盡量支持高版本的規(guī)范,以保證支持大多數(shù)工具生成的PDF文件。從1.4版本以后,PDF文件的版本并不唯一的只是在這里表示了,可能后面會改寫(catalog的Version詞條),所以解析PDF的時候,如果這里的版本大于等于1.4,應(yīng)該再比較一下catalog里面的version,取其中高一點的版本。2.對象集合這是一個PDF文件最重要的部分,文件中用到的所有對象,包括文本/圖象/音樂/視頻/字體/超連接/加密信息/文檔結(jié)構(gòu)信息等等,都在這里定義。格式如下:20obj...endobj一個對象的定義包含4個部分:歐陽治創(chuàng)編2021.03.10 歐陽治

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

創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10000000007400000n000000012000000n000000017900000n 其中,xref是開始標志,表示以下為一個交叉引用表的內(nèi)容;每個交叉引用表又可以分為若干個子段,每個子段的第一行是兩個數(shù)字,第一個是對象起始號,后面是連續(xù)的對象個數(shù),接著每行是這個子段的每個對象的具體信息——每行的前10個數(shù)字代表這個這個對象相對文件頭的偏移地址,后面的5位數(shù)字是生成號(用于標記PDF的更新信息,和對象的生成號作用類似),最后一位f或n表示對象是否被使用(n表示使用,f表示被刪除或沒有用)。上面這個交叉引用表一共有3個子段,分別有1個,1個,3個對象,第一個子段的對象不可用,其余子段對象可用。4.trailer: 通過trailer可以快速的找到交叉引用表的位置,進而可以精確定位每一個對象;還可以通過它本身的字典還可以獲取文件的一些全局信息(作者,關(guān)鍵字,標題等),加密信息,等等。具體形式如歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10下:trailer<<keylvaluelkey2value2key3value3…>>startxref553%%EOFtrailer后面緊跟一個字典,包含若干鍵-值對。具體含義如下:鍵值類型值說明Size整形數(shù)字所有間接對象的個數(shù)。一個PDF文件,如果被更新過,則會有多個對象集合、交叉引用表、trailer,^^一■個trailer的這個字段記錄了之前所有對象的個數(shù)。這個值必須是直接對象。Prev整形數(shù)字當(dāng)文件有多個對象集合、交叉引用表和trailer時,才會有這個鍵,它表示前一個相對于文件頭的偏移位置。這個值必須是直接對象。Root字典Catalog字典(文件的邏輯入口點)的對象號。必須是間接對象。Encrypt字典 文檔被保護時,會有這個字段,加密字典的對象號。Info 字典 存放文檔信息的字典,必須是間接對象。ID 數(shù)組 文件的IDstartxref:后面的數(shù)字表示最后一個交叉引用表相對于文件起始位置的偏移量。%%EOF:文件結(jié)束符. 一個PDF文件,都會有上面這樣的結(jié)構(gòu)(線性化優(yōu)化的PDF例外,這個后面單獨說)。實際一個pdf文件是很復(fù)雜的,但是上面幾個部分是確定的,只能多不能少.了解了PDF文件的物理結(jié)構(gòu),就可以提取出一個一個的對象了.PDF中的對象有8種:1.booleam歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10用關(guān)鍵字true或false表示,可以是array對象的一個元素,或dictionary對象的一個條目.也可以用在PostScript計算函數(shù)里面,做為if或ifesle的一個條件。2.numeric包括整形和實型,不支持非十進制數(shù)字,不支持指數(shù)形式的數(shù)字.例:1)整數(shù)1234567+111-2范圍:正2的31次方-1到負的2的31次方2)實數(shù)12.30.8+6.3-4.01-3.+.03范圍:±3.403X10的38次方士1.175X10的-38次方注意:如果整數(shù)超過表示范圍將轉(zhuǎn)化成實數(shù),如果實數(shù)超過范圍就出錯了3.string由一系列0-255之間的字節(jié)組成,一個string總長度不能超過65535.string有以下兩種方式:1)直接字串歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10由0包含起來的一個字串,中間可以使用轉(zhuǎn)義符,,/,,.例:(abc)表示abc(a//)表示a/轉(zhuǎn)義符的定義如下:轉(zhuǎn)義字符 含義/n 換行/r 回車/t 水平制表符/b 退格/f 換頁(Formfeed(FF))/( 左括號/) 右括號// 反斜杠/ddd 八進制形式的字符2) 十六進制字串由<>包含起來的一個16進制串,兩位表示一個字符,不足兩位用0補齊例:<Aabb>表示AA和BB兩個字符<AAB>表示AA和B0兩個字符4.name歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10由一個前導(dǎo)/和后面一系列字符組成,最大長度為127.和string不同的是,name是不可分割的和唯一的,不可分割就是說一個name對象就是一個原子,比如/name,不能說n就是這個name的一個元素;唯一就是指兩個相同的name一定代表同一個對象.從pdf1.2開始,除了ascii的0,別的都可以用一個#加兩個十六進制的數(shù)字表示.例:/name表示name/name#20is表示nameis/name#200表示name05.array用"包含的一組對象,可以是任何pdf對象(包括array).雖然pdf只支持一維array,但可以通過array的嵌套實現(xiàn)任意維數(shù)的array(但是一個array的元素不能超過8191)例:[5493.14false(Ralph)/SomeName]6.Dictionary歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10用"<<"和">>"包含的若干組條目,每組條目都由key和value組成,其中key必須是name對象,并且一個dictionary內(nèi)的key是唯一的;value可以是任何pdf的合法對象(包括dictionary對象).例:<</IntegerItem12/StringItem(astring)/Subdictionary<</Item10.4/Item2true/LastItem(not!)/VeryLastItem(OK)>>>>7.stream由一個字典,和緊跟其后面的一組關(guān)鍵字stream和endstream以及這組關(guān)鍵字中間包含一系列字節(jié)組成.內(nèi)容和string很相似,但有區(qū)別:stream可以分幾次讀取,分開使用不同的部分,string必須作為一個整體一次全部讀取使歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10用;string有長度限制,但stream卻沒有這個限制.一般較大的數(shù)據(jù)都用stream表示.需要注意的是,Stream必須是間接對象,并且stream的字典必須是直接對象。從1.2規(guī)范以后,stream可以以外部文件形式存在,這種情況下,解析PDF的時候stream和endstream之間的內(nèi)容就被忽略掉。例:dictionarystream…data…endstreamstream字典中常用的字段如下:字段名類型值Length整形(必須)關(guān)鍵字stream和endstream之間的數(shù)據(jù)長度,endstream之前可能會有一個多余的EOL標記,這個不計算在數(shù)據(jù)的長度中。Filter名字或數(shù)組(可選)Stream的編碼算法名稱(列表)。如果有多個,則數(shù)組中的編碼算法列表順序就是數(shù)據(jù)被編碼的順序。歐陽治歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10

歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10DecodeParms字典或數(shù)組(可選)一個參數(shù)字典或由參數(shù)字典組成的一個數(shù)F文件標識組,供Filter使用。如果僅有一個Filter并且這個Filter需要參數(shù),除非這個Filter的所有參數(shù)都已經(jīng)給了默認值,否則的話DecodeParms必須設(shè)置給Filter。如果有多個Filter,并且任意一個Filter使用了非默認的參數(shù),DecodeParms必須是個數(shù)組,每個元素對應(yīng)一個Filter的參數(shù)列表(如果某個Filter無需參數(shù)或所有參數(shù)都有了默認值,就用空對象代替)。如果沒有Filter需要參數(shù),或者所有Filter的參數(shù)都有默認值,DecodeParms就被忽略了。(可選)保存stream數(shù)據(jù)的文件。如果有這個字段,stream和endstream就被忽略,F(xiàn)Filter將會代替Filter,FDecodeParms將代替DecodeParms。Length字段還是表示stream和endstream之間數(shù)據(jù)的長度,但是通常此刻已經(jīng)沒有數(shù)據(jù)了,長度是0.FFilter名字或字典(可選)和filter類似,針對外部文件。FDecodeParms8.NULL字典或數(shù)組(可選)和DecodeParams類似,針對外部文件。用null表示,代表空.如果一個key的值為null,則這個key可以被忽略;如果引用一個不存在的object則等價于引用一個空對象.例:(略)以上八種對象是按照對象內(nèi)涵來分的,如果按照對象的使用規(guī)則來說,對象又分為間接對象和直接對象。間接對象是PDF中最常用的對象,如前面對象集合里面的,所有對象都是間接對象,歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10在其他位置通過R關(guān)鍵字來引用,在交叉引用表里面都是通過間接對象來引用的。直接對象就更好理解了,上面的8種對象單獨出現(xiàn)的時候就叫直接對象。PDF文件結(jié)構(gòu)(二) 邏輯結(jié)構(gòu)作者:bobob郵件:zxbbobob@要解析一個PDF文件,首先要掌握PDF的物理結(jié)構(gòu),這是第一步。但是這個僅僅只是基礎(chǔ),更重要的是對PDF邏輯結(jié)構(gòu)的解析。PDF的邏輯大體上是一個樹狀結(jié)構(gòu),根節(jié)點是catalog字典,通過這里去解析頁、目錄、鏈接信息等等,在這里按照PDF的樹形結(jié)構(gòu),詳細討論一下整個文件的邏輯框架。一、catalog根節(jié)點catalog是整個PDF邏輯結(jié)構(gòu)的根節(jié)點,這個可以通過trailer的Root字段定位,雖然簡單,但是相當(dāng)重要,因為這里是PDF文件物理結(jié)構(gòu)和邏輯結(jié)構(gòu)的連接點。Catalog字典包歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10含的信息非常多,這里僅就最主要的幾個字段做個說明。Pages字段這是個必須字段,是PDF里面所有頁面的描述集合。Pages字段本身是個字典,它里面又包含了一下幾個主要字段:字段類型值Typename(必須)只能為Pages。Parentdictionary(如果不是catalog里面指定的跟節(jié)點,則必須有,并且必須是間接對象)當(dāng)前節(jié)點的直接父節(jié)點。Kidsarray(必須)一個間接對象組成的數(shù)組,節(jié)點可能是page或pagetree。Countinteger(必須)pagetree里面所包含葉子節(jié)點(page對象)的個數(shù)。從以上字段可以看出,Pages最主要的功能就是組織所有的page對象。Page對象描述了一個PDF頁面的屬性、資源等信息。Page對象是一個字典,它主要包含一下幾個重要的屬性:字段類型值Typename(必須)必須是Page。Parentdictionary(必須;并且只能是間接對象)當(dāng)前page節(jié)點的直接父節(jié)點pagetree。歐陽治歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10

歐陽治歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10LastModifieddate(如果存在PieceInfo字段,就必須有,否則可選)記錄當(dāng)前頁面被最后一次修改的日期和時間。Resourcesdictionary(必須;可繼承)記錄了當(dāng)前page用到的所有資源。如果當(dāng)前頁不用任何資源,則這是個空字典。忽略所有字段則表示繼承父節(jié)點的資源。MediaBoxrectangle(必須;可繼承)定義了要顯示或打印頁面的物理媒介的區(qū)域(defaultuserspaceunits)CropBoxrectangle(可選;可繼承)定義了一個可視區(qū)域,當(dāng)前頁被顯示或打印的時候,它的內(nèi)容會被這個區(qū)域裁剪。默認值就是MediaBox。BleedBoxrectangle(可選)定義了一個區(qū)域,當(dāng)輸出設(shè)備是個生產(chǎn)環(huán)境(productionenvironment)的時候,頁面顯示的內(nèi)容會被裁剪。默認值是CropBox.Contentsstreamorarray(可選)描述頁面內(nèi)容的流。如果這個字段缺省,則頁面上什么也不會顯示。這個值可以是一個流,也可以是由幾個流組成的一個數(shù)組。如果是數(shù)組,實際效果相當(dāng)于所有的流是按順序連在一起的一個流,這就允許PDF生成的時候可以隨時插入圖片或其他資源。流之間的分割只是詞匯上的一個分割,并不是邏輯上或者組織形式的切割。Rotateinteger(可選;可繼承)順時鐘旋轉(zhuǎn)的角度數(shù),這個必須是90的整數(shù)倍,默認是0。Thumbstream(可選)定義當(dāng)前頁的縮略圖。Annotsarray(可選)和當(dāng)前頁面關(guān)聯(lián)的注釋。Metadatastream(可選)當(dāng)前頁包含的元數(shù)據(jù)。一個簡單例子:30obj<</Type/Page/Parent40R歐陽治歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10/MediaBox[00612792]/Resources<</Font<</F370R/F590R/F7110R>>/ProcSet[/PDF]>>/Contents120R/Thumb140R/Annots[230R240R]>>endobjOutlines字段Outline是PDF里面為了方便用戶從PDF的一部分跳轉(zhuǎn)到另外一部分而設(shè)計的,有時候也叫書簽(Bookmark),它是一個樹狀結(jié)構(gòu),可以直觀的把PDF文件結(jié)構(gòu)展現(xiàn)給用戶。用戶可以通過鼠標點擊來打開或者關(guān)閉某個outline項來實現(xiàn)交互,當(dāng)打開一個outline時,用戶可以看到它的所有子節(jié)點,關(guān)閉一個outline的時候,這個outline的所有子歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10節(jié)點會自動隱藏。并且,在點擊的時候,閱讀器會自動跳轉(zhuǎn)到outline對應(yīng)的頁面位置。Outlines包含一下幾個字段:KEYTYPEVALUETypename(可選)如果這個字段有值,則必須是Outlines。Firstdictionary(必須;必須是間接對象)第一個頂層Outlineitem。Lastdictionary(必須;必須是間接對象)最后一個頂層outlineitem。Countinteger(必須)outline的所有層次的item的總數(shù)。Outline是一個管理outlineitem的頂層對象,我們看到的,其實是outlineitem,這個里面才包含了文字、行為、目標區(qū)域等等。一個outlineitem主要有一下幾個字段:Titletextstring(必須)當(dāng)前item要顯示的標題。Parentdictionary(必須;必須是間接對象)outline層級中,當(dāng)前item的父對象。如果item本身是頂級item,則父對象就是它本身。Prevdictionary(除了每層的第一個item外,其他item必須有這個字段;必須是間接對象)當(dāng)前層級中,此item的前一個item。Nextdictionary(除了每層的最后一個item外,其他item必須有這個字段;必須是間接對象)當(dāng)前層級中,此item的后一個item。Firstdictionary(如果當(dāng)前item有任何子節(jié)點,則這個字段是必須的;必須是間接對象)當(dāng)前item的第一個直接子節(jié)點。Lastdictionary(如果當(dāng)前item有任何子節(jié)點,則這個字段是必須的;必須是間接對象)當(dāng)前item的最后一個直接子節(jié)點。歐陽治歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10歐陽治歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10Destname,bytestring,orarraydictionary(可選;outline如果ADestname,bytestring,orarraydictionary(可選;outline如果A字段存在,則這個不能被會略)當(dāng)前的item被激活的時候,要顯示的區(qū)域。(可選;outline如果Dest字段存在,則這個不能被忽略)當(dāng)前的item被激活的時候,要執(zhí)行的動作。URI字段URI(uniformresourceidentifier),定義了文檔級別的統(tǒng)一資源標識符和相關(guān)鏈接信息。目錄和文檔中的鏈接就是通過這個字段來處理的。(4)Metadata字段文檔的一些附帶信息,用xml表示,符合adobe的xmp規(guī)范。這個可以方便程序不用解析整個文件就能獲得文件的大致信息。(5)其他Catalog字典中,Catalog字典中,常用的字段一般有以下一些字段類型值Typename(必須)必須為Catalog。Versionname(可選)PDF文件所遵循的版本號(如果比文件頭指定的版本號高的話)。如果這個字段缺省或者文件頭指定的版本比這里的高,那就以文件頭為準。一個PDF生成程序可以通過更新這個字段的值來修改PDF文件版本號。Pagesdictionary(必須并且必須為間接對象)當(dāng)前文檔的頁面集合入口。歐陽治創(chuàng)編2021.03.10歐陽治創(chuàng)編2021.03.10

歐陽治創(chuàng)編2021.03.10 歐陽治創(chuàng)編2021.03.10PageLabelsnumbertr(可選)numbertree,定義了頁面和頁面label對應(yīng)ee 關(guān)系。Names

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論