


高文(1967.01-),男,漢族,山東淄博,碩士,高級講師,研究方向:電子信息和軟件等。
摘要:相較于位圖,SVG圖形具有縮放不影響清晰度的優勢,因此,SVG技術在圖標、Logo設計等領域廣泛運用。目前,SVG圖像可以在計算機等終端較為方便地顯示。但隨著智能穿戴設備的發展,在手環、智能手表等嵌入式設備上顯示SVG圖像的需求日益增長。基于此,本文提出了一種SVG文件的解析方法和將SVG技術植入嵌入式設備的解決方案。
關鍵字:SVG;矢量圖;嵌入式;XML解析
一、引言
近年來隨著科技進步,可穿戴的智能設備得到了飛速發展。AR眼鏡,智能手表,智能手環等產品不斷涌現,在移動設備的屏幕上顯示各類圖形的需求隨之日益增長。SVG(Scalable Vector Graphics)圖形因其占用內存小、顯示清晰度高等優點逐漸走進大家的視野。SVG的技術特點與嵌入式設備的現實需求高度契合,將SVG植入嵌入式設備以代替傳統位圖顯示圖像成為重要的發展方向[1]。
二、矢量圖與位圖
在計算機領域,圖像可分為位圖和矢量圖兩類,其中位圖又稱作點陣圖,即在二維平面中用帶有顏色信息的像素點描述圖像[2],也可將位圖想象為細密的網格,在網格中填充上顏色即可構成圖像。在相同的長寬下,網格越小則圖像分辨率越高,視覺上圖像就越清晰。在圖像處理中,將每個這樣的網格中的一格稱為一個像素,像素信息通常由諸如相機、手機等數字設備捕獲并按照一定規律排布存儲得到。位圖的清晰度與像素點的個數高度相關,如果將一張位圖的長、寬都放大,圖像會變得模糊,這是因為由于圖像變大,大量非原始的圖像數據被填充到了圖像的放大區域中,而能有效描述圖像的像素點個數并沒有改變。
矢量圖又被稱為面向對象的圖像,是由數學語言精確描述出來的一系列曲線和形狀構成的圖形,能夠有效克服位圖由圖像縮放而引起的清晰度降低的問題。矢量圖將一幅完整的圖形拆分為許多幾何圖形來描述,如橢圓,矩形等,并記錄這些幾何圖像的形狀、角度、彎曲程度等信息。無論矢量圖被放大或縮小,這些幾何圖形的形狀、角度等都不會改變,僅僅是圖形的大小被等比例地縮放,因此,矢量圖的縮放不會影響其清晰度,這是矢量圖對比位圖而言的最大優勢所在。
三、SVG技術
(一)SVG圖形介紹
SVG(可縮放矢量圖形)是由國際互聯網標準組織(World Wide Web ConSortium)于2000年指定的一種基于Extensible Markup Language (XML)的二維矢量圖形格式,后于2003年成為網絡矢量圖形的推薦標準。一方面,SVG是XML文件,因此,SVG圖像可由絕大多數文本編輯器創建和編輯,這為SVG圖像的使用提供了極大的便利。另一方面,SVG圖像的顯示可由多數主流瀏覽器完成,如谷歌Chrome,Microsoft edge等,能夠十分便捷地查看SVG圖像。此外,SVG提供了一套通用的矢量圖形繪制方法,促進了SVG技術世界范圍內的技術交流和發展。
矢量圖的核心思想在于將一幅完整圖像抽象為特定的圖例模式,圖形的存儲由記錄其模式特征完成,而非記錄像素點的原始信息。具體表現在用特定曲線描述并存儲各圖例的外形特征,并用某一類顏色模式,例如純色填充、漸進梯度色彩等,描述圖例內部的色彩圖案。這種抽象記錄圖形特征的圖像存儲方式和人類的視覺模式更為相似,例如,人類在認識蘋果這個事物的時候,大腦分析并記憶的是其接近于球體的外形特征和淺紅色的色彩特征。矢量圖中一些簡單的圖例模式僅需要數個特征數值便能夠被完整地描述,例如,矩形僅需要記錄其四個頂點坐標、四條邊的顏色、寬度以及矩形內部的填充顏色。現實世界的多數圖形都是由這些基礎圖層構成,而對于存在的其余各種曲線也僅需要記錄曲線的幾個關鍵參數即可。位圖模式下需要記錄每一個像素點的顏色和位置信息,在做放大處理時,即便采用填充算法填補像素點間的空隙,也會出現邊緣模糊、鋸齒等現象。相較于此,矢量圖記錄圖像的方式能夠極大地節約存儲空間,并使得圖像具有了良好的縮放性[3]。因此,矢量圖在記錄圖標、標識等簡單幾何圖案時具有顯著優勢。
(二)SVG圖形繪制
SVG使用XML格式對圖像進行定義,書寫規則和文件結構與XML相似。SVG文件以lt;svggt;元素開始,其中lt;svggt;和lt;/svggt;分別為文件的開始標簽和結束標簽,如圖1所示。
SVG的核心部件為路徑(Path)元素,它代表可進行顏色填充或描邊的輪廓,存儲了圖形的邊界信息、顏色填充規則和描邊規則等內容。一條路徑由lt;pathgt;標簽開始,其中d為路徑的屬性,存放路徑的邊界信息,而“fill”,“stroke”,“stroke-width”為d屬性中的命令,存儲填充、描邊方法等內容。在存放邊界信息的屬性d中包含“M”,“L”,“Z”等指令,其常用指令的含義如表1所示。
圖1中的SVG指令表示,以 (50,150) 坐標點作為id為“path”路徑的起始點;使用直線將起始點與點 (150,50) 相連接;使用直線將上一點與點 (150,150) 相連接;使用直線將上一點與點 (50,150) 相連接;閉合并結束當前路徑;設置路徑顏色為紅色;設置路徑線條寬度為5;路徑內部不進行填充。使用上述指令繪制出的SVG圖形如圖2所示。使用任意文本編輯器去修改SVG文件路徑中的點的坐標、顏色填充等信息,即可對所繪制的圖形進行相應調整,因此,SVG對圖形的創建和修改十分友好。
(三)嵌入式解決方案
SVG文件所繪制的圖形在計算機上顯示十分方便,用主流瀏覽器即可在線瀏覽。而現如今,各類嵌入式設備都有著大量的圖形顯示需求,如車載儀表盤、智能手表等可穿戴設備,還有顯示盤、家用電器顯示界面等。由于SVG圖形縮放性良好、文件占用內存小、顯示圖像清晰度高、顯示功耗低等優點,將SVG圖形代替傳統位圖在嵌入式設備上進行繪制顯示已逐漸成為當前的發展趨勢。因此,一套嵌入式設備的SVG圖像繪制和顯示方案顯得十分必要。在計算機方面,各大瀏覽器開發商利用計算機CPU對SVG文件進行解析后,在瀏覽器內部對SVG圖像進行繪制和顯示。而想要在嵌入式設備上顯示SVG圖像,首先需要研究一套對SVG文件的解析方案。基于此,本文提出了一種解析SVG文件的方法:利用設計的SVG解析器讀取XML格式的SVG字符串,逐行解析并按照一定的數據結構存儲SVG文件信息。
SVG解析器的核心思想在于,利用SVG文件內的“lt;”和“gt;”符號對其內容進行劃分。通過研究SVG官方文檔并結合XML語言特征可分析得到,SVG的屬性標簽均以“lt;”符號為開始標志,以“gt;”符號作為結束標志。SVG文件含有大量符號的字符串,解析器的目標在于合理地讀取和分析字符串內容并記錄有效數據。
以圖1的SVG實例為例介紹解析過程。SVG解析器定義了指針p對SVG文件進行逐字符的掃描,并定義了兩個指針sp和ep,用于分別記錄當前字符串的起始位置和終止位置。當解析器開始工作后,逐字符地掃描本文中的字符串,并在掃描確認當前解析內容為符號“lt;”時,用指針sp記錄下當前位置;指針p繼續掃描,在掃描確認當前解析內容為符號“gt;”時,用指針ep記錄下當前位置,由此獲得第一段待解析的內容,即以指針sp所指位置為起始點、以指針ep所指位置為中止點的字符串。每次獲得待解析內容的位置后,首先刪除字符串起始的空格、換行符等符號,然后讀取以字母開頭且以空格作為結尾的字符串,再將其與SVG各元素,如“svg”,“path”,“circle”等相比較,分析得到當前解析的元素。
例如,圖1第一行解析得到的內容為“svg”,解析器便將元素解析開始的標志位置為1。緊接著,指針p繼續掃描,直到掃描到path標簽前的“lt;”符號,指針sp記錄當前位置;繼續掃描至下一個“gt;”符號,指針ep記錄當前位置。然后,將指針sp與指針ep間的字符內容作為第二段待解析的字符串,可解析得到第一個以英文字符開頭且以空格字符結尾的字符串為“path”。由此,解析器將代表解析path的標志位置為1,其余內容將解析并存儲至歸屬于path元素的結構體內。依次解析當前字符串內的其余內容,例如“id”,“stroke”,“fill”等這類屬性,可以直接用字符串的格式存儲其對應的數據。但例如“data”等含有具體數值的屬性,需要先將字符串所表示的數值轉換為整型或者是浮點型的數據后,再對應進行存儲,以便后續在嵌入式設備中的使用。按照上述方法繼續解析可得到下一段解析字符串為“svg”,在元素解析開始標志位為1且再一次解析得到“svg”元素時,表示當前SVG文件解析結束,至此便完成了一次完整的解析流程。
(四)復雜元素解析的研究
對于SVG中單個基礎圖形的繪圖命令的解析較為容易,但在SVG中,同樣存在描述較為復雜的繪制指令,以下將用path和pattern元素為例,分析較為復雜命令的解析方法。
Path指令的解析由前文的介紹可知,path元素中存儲圖形輪廓信息的d屬性以M指令開始,并以Z指令結束。在實際的路徑中可能存在多個Z指令,即一個路徑元素下包含有多個子路徑,單純地將Z指令解析為封閉,并結束當前路徑出現繪圖錯誤的問題。例如,一個圓環的常規繪制邏輯為:繪制兩個圓心相同但半徑不同的圓形,然后利用填充屬性將兩個圓的路徑內部填充上某個顏色。上述兩個圓形的輪廓信息存儲在路徑元素的d屬性下,并用Z指令將其分開。Z指令的基礎含義為閉合當前路徑并結束,而閉合當前路徑的含義為:如果當前路徑的最后一個坐標點不與起始點重合,則將該點與起始點連接,以形成閉合路徑;若當前路徑的最后一個坐標點與起始點重合,則僅結束當前路徑。依此邏輯繪制上述圓環時,其中一個圓形繪制完成,遇到Z指令便會閉合當前圓形并填充顏色;然后繪制另一個圓形,遇到Z指令后再一次閉合當前圓形并填充顏色,這就導致繪制出的圖形變為了一個實心的圓形圖案,而并非圓環圖案。
產生該問題的本質原因在于顏色填充區域由兩個圓形的路徑所共同決定,是兩條路徑所包夾的區域,而上述繪圖邏輯將同一段路徑的兩段子路徑解析為兩個獨立的個體。解決方法在于應將Z指令解析為兩層含義:其一是解析為封閉當前路徑,即連接當前點與起始點的“close”命令;其二是解析為結束當前路徑的“end”命令。具體表現為,當在解析一個path元素的標簽時,若在一段d指令的中間位置識別到Z指令,則將其解析為“close”命令,即僅閉合當前路徑;若在一段d指令的中止位置識別到Z指令,則將其解析為封閉當前路徑并結束繪制,然后再按照填充規則對路徑進行顏色填充。上述解析邏輯將復雜路徑解析為多條相互關聯的子路徑,并在所有子路徑繪制完成后再進行顏色填充,有效維持了子路徑間的相互作用關系,從而避免多段子路徑獨立繪制所引起的繪制錯誤問題。
Pattern指令的解析在SVG中,為了方便繪制由大量子圖形構成的復雜組合圖形,引入了pattern元素,可以將其理解為在SVG中包含一定規則的繪圖模式,通常可以用純色或是梯度漸變色對一段封閉路徑進行填充。但在實際生產生活中,同樣存在用某個圖形對封閉區域進行填充的需求。例如,在繪制了一個矩形區域后,使用面積較小的三角形對該矩形逐行進行填充,即可得到內部填充滿三角形的矩形圖案;進一步地,再使用圓形對這些三角形逐行填充,即可得到內部充滿三角形的矩形圖案,且三角形內部充滿圓形;還可以用其他圖形繼續填充上述圓形。不難發現,這種繪圖模式會使得繪圖工作量呈指數型的增長。
本文提出一種遞歸的繪制方法,用以完成上述復雜圖形的繪制,具體為:在需要繪制內部填充滿三角形的矩形時,首先繪制出三角形;但三角形內部需要由圓形填充,所以先繪制出圓形;進一步判斷圓形內部是否還有其他填充圖形,若有則先繪制出該填充圖形,若沒有,則用某一純色或是漸變色填充;在繪制出圓形后,使用圓形填充三角形,以得到鋪滿圓形的三角形,再用該三角形填充矩形即可繪制出期望的圖形;以此遞歸的方式從最底層元素開始逐層繪制圖形并填充至上一層,直至繪制出最外層圖形。
用SVG解析器對pattern指令的具體解析流程如下:當前指針p解析到pattern元素后,將解析器中的pattern標志位置為1,以開始pattern模式的解析;然后解析字符串的內容,如果當前pattern圖形的填充方式為用鏈接的其他pattern子圖填充,則僅記錄該子圖的“id”屬性,并用鏈表的形式存儲該pattern模式的細節信息;繼續解析“id”所匹配的pattern子圖,再次判斷該子圖的填充模式,如果其填充方式仍為使用其他pattern子圖填充,則同樣僅記錄該子圖的“id”屬性;逐層解析,直至解析到當前pattern子圖的填充規則為純色或漸進色彩填充,則繪制出當前子圖;緊接著,遍歷存儲pattern模式的鏈表,查詢得知填充模式為該子圖的pattern節點,并用該子圖完成圖形填充;以此方法遍歷鏈表,直至完成所有的pattern子圖的繪制,最后用pattern圖形完成最外層圖形的填充。
這種遞歸的繪圖方法解決了復雜SVG圖形的繪制問題,逐層繪制的方法能夠十分容易地提取出任意一層的pattern子圖,并穿插至其余圖形的繪制中。此外,在嵌入式設備資源滿足的情況下,理論上該方法可以無限遞歸地繪制嵌套的復雜圖形。
四、結束語
本文所提出的SVG解析器采用C語言完成編寫,在計算機上編譯后,可燒錄至嵌入式設備,如含有圖像芯片的顯示設備。然后,將需要顯示的SVG文件存儲至嵌入式設備中,用SVG解析器對其進行解析,得到各圖例的屬性、繪圖命令等信息,便可利用嵌入式設備的繪圖接口將SVG圖形顯示至屏幕上,從而實現SVG文件在嵌入式設備的在線解析和顯示。
作者單位:高文 淄博市工業數字經濟發展中心
參" 考" 文" 獻
[1]張弘.基于FPGA的視頻圖像處理的研究與實現[D].成都:電子科技大學,2020.
[2]張衛正.基于視覺與圖像的植物信息采集與處理技術研究[D].杭州:浙江大學,2016.
[3]趙海英,李煥洪,侯小剛.基于感知驅動的紋飾矢量圖評價方法[J].北京郵電大學學報,2021,44(06):53-58.