詳細剖析了CAD的圖形交換格式———DXF檔案的結構,分析了SVG檔案的架構元素和圖形元素,建立了CAD中的對象、DXF檔案中的實體和SVG中的元素三者之間的對應表,并對轉換中遇到的難點問題提出了解決方案,最後,通過程式設計實作驗證了方法的可行性。來源:SVG中國(ChinaSVG.COM) [SVG中國專題文章]
引言
目前CAD技術已廣泛應用于建築設計、機械設計、城市規劃、交通等領域,由其主流軟體AutoCAD或在之基礎上二次開發的軟體生成的圖紙層出不窮。SVG(Scalable Vector Graphics,可縮放的矢量圖形)基于XML标準,既具有開放性,檔案較小,顯示放縮不損失品質等優點,又有強大的動畫互動功能和豐富的濾鏡效果。盡管現在已有一些SVG圖形的生成工具,但為了充分共享已有的CAD檔案,使之能運用于WebGIS或圖形釋出,是以有必要探讨将CAD檔案有效地轉換為SVG檔案的問題。
AutoCAD的主要圖形格式為DWG檔案和DXF檔案,AutoCAD公司直今未公開DWG檔案格式,如要直接讀取DWG檔案,就需要分析其二進制資料,破譯其格式,這種工作相對很困難。另一種方法是利用AutoCAD的二次開發技術,使用如ADS、ObjectARX、VBA、Visual Lisp等開發語言直接通路AutoCAD提供的一組ActiveX接口,擷取圖形檔案中各個圖形對象的有用資訊,然後使用SVG中相應的元素來描述這些圖形對象。但這種方法不能完全脫離AutoCAD平台,應用不夠靈活。現在國外對DWG格式的研究也有很多,較為著名的是OpenDWG協會的ODT軟體包,該軟體包為直接操作DWG檔案提供了豐富的函數。但要利用此軟體包必須是會員,并且需要繳費,在非盈利條件下可以免費使用。DXF是AutoCAD提供的圖形交換格式,它以ASCII碼格式存儲檔案,可以用記事本編輯,簡單易讀,應用廣泛。DXF在表現圖形的大小方面十分精确,本文主要探讨了DXF檔案轉換到SVG檔案的一系列問題。
1 DXF格式剖析
DXF格式是标記AutoCAD圖形檔案中所包含的全部資訊的一種表示方法,最小組成機關是組,每組占兩行,第一行是組碼,是一個整數,表明了其後資料元素的類型,也指出了資料元素對于給定對象(或記錄)類型的含意;第二行是組值,資料類型根據組碼的數值可以是字元串型、整型或浮點數型等。一個DXF檔案分為七個區域(如圖1),每個區域均由多個組組成。每個區域都是以組碼0開始,其後跟随着字元串SECTION,接着是組碼2和表示區域名稱的字元串(例如HEADER),當出現組碼0,其後跟随字元串ENDSEC時表示該區域結束。所有區域都結束後,在DXF檔案的最後是組碼0,後跟組值為字元串EOF作為檔案的結束标志。圖2是DXF檔案中的HEADER區域。一個DXF檔案可以隻包含七個區域中的若幹個區域,而不是全部區域。七個區域中,最重要的是ENTITIES區域。一個最簡單的DXF檔案可以隻包含ENTITIES區域,而不需要包含其他任何區域,這樣就大大降低了DXF檔案編寫的難度。
HEADER區域 |
CLASSES區域 |
TABLES區域 |
BLOCKS區域 |
ENTITIES區域 |
OBJECTS區域 |
THUMBNAIL IMAGE區域 |
表1 DXF檔案的組織結構
SECTION 2 HEADER | HEADER區域的開始 |
9 $<變量> <組碼> <值> | 重複每一頭部變量 |
ENDSEC | HEADER區域結束 |
表2 DXF檔案中的HEADER區域
DXF檔案完整的組織結構說明如下:
- HEADER區域:包含圖形的基本資訊,由一個AutoCAD資料庫版本号和許多系統變量組成。
- CLASSES區域:包含有關應用程式定義類的資訊,這些類的執行個體包含在BLOCKS區域、ENTITIES區域和OBJECTS區域的資料庫中。
- TABLES區域:包含一系列符号表的定義。這些符号表包括:APP ID(應用程式辨別表) 、BLOCK_RECORD (塊引用表) 、DIMSTYLE (标注樣式表) 、LAYER (圖層表) 、LTYPE (線型表) 、STYLE (文本樣式表) 、UCS(使用者坐标系表) 、VIEW (視圖表)和VPORT(視口配置表) 。
- BLOCKS區域:包括塊定義群組成圖形中每個塊引用的圖形圖元。
- ENTITIES區域:包含圖形中的所有圖形對象(包括點、線、面、插入塊,注記文字等實體) ,其中包括塊引用。
- OBJECTS區域:包含圖形中的非圖形對象。
- THUMBNAIL IMAGE區域:包含圖形中的預覽圖像。
2 SVG檔案的結構分析
SVG矢量圖形具有很多優點,與目前網絡流行的點陣圖
像格式GIF和JPEG相比, SVG能任意對圖形顯示進行放縮
而保證圖像品質,不會出現點陣圖常見的鋸齒邊緣,檔案容量相對較小,存儲效率高,下載下傳速度快;與矢量動畫軟體Flash制作的圖形相比,也具有一些優勢,比如Flash的檔案僅能用Flash軟體編輯,不利于文檔的更改和維護,而SVG圖形能用任意的文本編輯工具編輯; Flash的檔案與通用的标準技術間缺乏互操作性,如缺乏與HTML 頁面或CSS表單互動的機制,而SVG能嵌入到HTML 頁面中,支援事件程式設計,能通過XSL或CSS的方法添加各種樣式等。
SVG是XML的擴充,在文法和格式上是XML 規範的一部分,但不屬于XML 所能解釋的範疇。SVG文檔區分大小
寫,具有XML的基本屬性 :
- 所有的标記都有開始标記和結束标記,否則必須注明為空标記。空标記用反斜杠結束,如< line / >。
- 标記必須正确嵌套。如果一個标記在另一個标記中開始,那麼它也必須在那個标記中結束。
- 文檔必須隻有一個根。一個< svg > < / svg > 元素包含了一個SVG文檔的所有内容。
- 文檔應該以XML 聲明< ? xml version = ”1. 0”? >開始。
- 文檔應該包含一個DOCTYPE聲明, 該聲明指向一個允許元素的清單。
SVG 1. 0 文檔的DOCTYPE聲明是:
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTDSVG1.0//EN"" http://www.w3.org/TR/2001/REC2SVG220010904/DTD/svg10.dtd">
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg">
</svg>
SVG圖形包括架構元素和圖形元素。架構元素能夠包含圖形元素和其他架構元素,如:<svg>、<g>、<defs>、<symbol>、<clipPath>、<mask>、<pattern>、<marker>、<a>和<switch>。<g>元素是編組元素,能分組圖形對象,便于管理和使用,如對組進行變換或提供一個公共屬性。<defs>元素定義可重用部件,以後可在圖形主體中調用,這種重用技術最大限度地利用了HTTP的緩存功能,避免了資料的重複下載下傳。調用<defs>元素定義的項有兩種方式,一種是定義的項通過其本地URL(或URI)引用;第二種是使用<use/>元素。
例如: <use xlink:href="#block1"/>
圖形元素包含路徑<path>、文字<text>、圖像<image>、<use>和六種基本形狀:矩形<rect>、圓<circle>、橢圓<ellipse>、線<line>、折線<polyline>、多邊形<polygon>,簡單圖形直接由基本形狀建構,每個基本形狀都帶有位置、大小、顔色、輪廓等屬性。複雜圖形可以用路徑<path>來描述,路徑是一系列指令,用來建立作為圖像一部分精确定義的形狀,該形狀可以是開放的或閉合的,并可以包含一條或多條線、曲線和線段,其中曲線可用圓弧、三次或兩次的Bezier曲線繪制。SVG提供了對嵌入圖像的支援,可以在<image>直接寫入圖像的二進制資訊,也可以連結指向某個圖像檔案,還可以用濾鏡中的<feImage>引入外部圖像檔案加以處理。SVG在字型處理上采用了CSS 2中的字型顯示核心技術Web Font,保證在任何情況下看到的字型相同。SVG通過<transform>可以實作坐标轉換,實作圖形放縮、旋轉、鏡像、傾斜等效果。
3 DXF檔案轉換為SVG檔案
分析DXF檔案和SVG檔案,發現兩者在表示方式上有一定的相似之處,兩者均是文本檔案,通過記錄圖形的特征資料來描述矢量圖形,比如圓,兩者均記錄了圓心、半徑等資料。但在有些圖形的描述上,記錄的特征資料是不同的,比如橢圓等。是以,實作CAD檔案到SVG檔案的轉換,不僅要分析AutoCAD中的每一類型的二維矢量圖形對象在DXF檔案中的對應實體描述,以及SVG中對應于DXF檔案中的實體的元素,而且應針對DXF記錄的特征資料利用相應的公式推導出SVG需要的資料。經過詳細深入的分析,得到AutoCAD中的對象、DXF檔案中的實體和SVG中的元素之間的對應如表1所示。
表1 AutoCAD中的對象、DXF檔案中的實體和SVG中的元素對應表
AutoCAD中的圖形對象 | DXF檔案中的實體 | SVG中對應的元素 |
矩形、多邊形、多段線 | LWPOLYLINE | polyline |
圓 | CIRCLE | Circle |
橢圓 | ELLIPSE | ellipse、rotate |
直線 | LINE | line |
圓弧 | ARC | path |
橢圓弧 | ELLIPSE | path |
樣條曲線 | SPLINE | path |
圖塊和塊引用 | BLOCK、INSERT | defs、g、use等 |
文字 | TEXT、MTEXT | text |
圖像 | IMAGE | image |
多線 | MLINE | polyline |
圖案填充 | HATCH | defs、g、use等 |
參照線 | XLINE | line |
尺寸 | DIMENSION | defs、g、use等 |
在轉換的過程中,會遇到一些難點,下面提出具體的解決方案:
3.1 坐标系統
不管是AutoCAD中的對象還是SVG中的圖形都是通過坐标定位的。但是兩者的坐标系統是不同的, AutoCAD的世界坐标系的原點在螢幕的左下角, X軸的正向朝右, Y軸的正向向上。SVG的坐标系的原點在初始視口(螢幕)的左上角,X軸的正向朝右, Y軸的正向朝下。兩者均可以定義自己的坐标系。在DXF檔案向SVG檔案轉換時,為保證圖形顯示正确,應将所有的圖形進行坐标矩陣變換。在SVG中使用下面語句:
<g transform="matrix(1 0 0 21 0 600)">
</g>
3.2 橢圓
由于在DXF檔案中的橢圓記錄的特征資料和SVG中的橢圓元素需要的資料是不同的, DXF檔案記錄了橢圓圓心、長軸的端點(相對于圓心的相對值) 、半長軸與半短軸的比例等資料。SVG中的橢圓元素需要橢圓圓心、半長軸、半短軸等資料。并且AutoCAD中的橢圓的長軸可以和水準軸成任意角度,但直接用SVG中的< ellip se >元素所繪的圖形隻能使橢圓的長軸平行于水準軸,是以,需要計算長軸和水準軸所成角度,再使用旋轉變換。是以應利用下面公式轉換:
sl = S qr( x23 x2 + y23 y2)
ss = sl3 r1
aa = A tn ( y2 / x2) 3 180 /3. 141 592 6
其中sl代表橢圓的半長軸, ss代表橢圓的半短軸, aa代表橢圓的長軸與水準軸的角度, x2和y2是長軸的端點(相對于圓心的相對值) , r1是半長軸與半短軸的比例。
3.3 文字
對所有圖形進行了坐标系統轉換,但文字不同于其他圖形,轉換之後會出現了反轉,這時應先将文字相對于原所在位置的基線進行鏡像,這樣能保證文字按正常狀态顯示。
轉換之後,可能出現SVG中的中文不能顯示的情況,這是因為SVG有3種編碼形式: iso2885921 (ASCII) 、utf28和utf216, iso2885921 (ASCII)不能直接使用漢字字元, utf28和utf216是Unicode形式的編碼, utf28支援多語種,每一個ASCII字元使用一個位元組來表示,對于其他字元使用三個位元組來表示。utf216對于任何一個字元都是使用兩個位元組來表示,這兩種編碼能正常顯示漢字。在程式設計時,如果直接寫SVG文檔,則文檔使用的是ASCII碼,是以不能正常顯示漢字。解決的方案是:
3.3.1 在SVG中,需要将中文字型名稱進行“國際化”,即将漢字字型名稱改為英文名稱,下面是部分字型對照清單(表2) 。
表2 部分漢字字型與英文名稱對照表
英文名稱 | 漢字字型 | 英文名稱 | 漢字字型 |
FangSong_GB2312 | 仿宋_GB2312 | KaiTi_GB2312 | 楷體_GB2312 |
YouYuan | 幼圓 | LiSu | 隸書 |
SimSun | 宋體 | SimHei | 黑體 |
3.3.2 将ASCII碼的文檔轉換成Unicode編碼後寫檔案。下面是VB 實作的代碼,将ASCII碼的文檔讀入byte 數組mem,通過StrConv( )轉換後,寫入檔案。
fLength = FileLen (" c: / svg1. svg" )
ReDim mem (fLength) AsByte
Open "c: / svg1. svg" For Binary As #2
Get #2, , mem
Close #2
mem = StrConv(mem, vbUnicode, &H804)
Open svgfilename For Binary As #3
Put #3, , mem
Close #3
3.4 圓弧、橢圓弧
對于圓弧、橢圓弧等複雜圖形,在SVG中用< Path >元素
描述,其中有橢圓弧指令:
A rx ry x2axis2rotation large2arc2flag sweep2flag x y
其中, rx和ry分别是半長軸和半短軸, x2axis2rotation是弧所在橢圓的X 軸與水準方向的夾角, large2arc2flag 和sweep2flag決定橢圓弧的繪制方向,如果large2arc2flag為1代表大角度弧線,為0代表小角度弧線, sweep2flag為1代表起點到終點的弧線繞橢圓中心是順時針方向,為0是逆時針方向, x和y是橢圓弧終點坐标。這和DXF中的圓弧、橢圓弧描述的特征資料是不一樣的,同樣需要轉換。
3.5 圖塊
為了提高繪圖效率, AutoCAD中提供了圖塊對象。在DXF中,圖塊定義在TABLES 區域,在ENTITIES區域通過INSERT組碼存儲圖塊調用資訊。轉換成SVG時,将圖塊定義用<defs>來組織,圖塊名作為每個defs元素的ID屬性,使用<use>元素調用圖塊資訊。這種方式支援圖塊的嵌套。
3.6 圖層
圖層是AutoCAD中的一種非常有用的圖形管理方式,将圖形對象分門别類放在不同的圖層中,便于使用者管理、編輯和列印。在轉換器中,實作了根據圖層有選擇轉換圖形,極大地增強了靈活性。
4 應用執行個體
根據上述分析,筆者利用VB程式設計實作了二維矢量圖形從DXF檔案到SVG檔案的轉換,實作算法如下:
- 選擇DXF檔案後,進行DXF檔案讀,顯示圖形所包含的所有圖層。
- 輸入目标檔案名。
- 選擇要轉換的圖層。
- 進行DXF檔案到SVG檔案的轉換:
- 首先對一個臨時SVG檔案進行初始化。
- 根據從DXF檔案中讀出的組碼群組值判斷對象的類型,不同類型的對象取得不同的屬性。
- 進行必要的屬性轉換,對每個不同對象用SVG中相應的元素來描述。
- 将轉換後的結果寫到臨時的SVG檔案中。
- 将臨時的SVG檔案進行從ASCII碼到Unicode編碼的轉換。
- 将Unicode編碼以二進制方式寫入目标檔案。
圖1 通過轉換器轉換後得到的SVG圖形
5 結語
本文詳細剖析了DXF檔案的結構,并且分析了SVG檔案的基本要素和架構要素,建立了CAD中的對象、DXF檔案中的實體和SVG中的元素三者之間的對應表,并對轉換中遇到的坐标系統轉換、文字顯示、圖塊、複雜圖形的顯示等多個問題提出了解決方案,最後,通過VB程式設計實作驗證了方法的可行性。這種轉換方法完全不依賴于AutoCAD平台,靈活高效,具有一定的實用價值。